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";
149 protected BBInputSetup bbInputSetup;
151 protected BBInputSetupUtils bbInputSetupUtils;
153 private ExceptionBuilder exceptionBuilder;
155 private CatalogDbClient catalogDbClient;
157 private AAIConfigurationResources aaiConfigurationResources;
159 private WorkflowActionExtractResourcesAAI workflowActionUtils;
161 private VrfValidation vrfValidation;
164 private Environment environment;
165 private String defaultCloudOwner = "org.onap.so.cloud-owner";
167 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
168 this.bbInputSetupUtils = bbInputSetupUtils;
171 public void setBbInputSetup(BBInputSetup bbInputSetup) {
172 this.bbInputSetup = bbInputSetup;
175 public void selectExecutionList(DelegateExecution execution) throws Exception {
177 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
178 ServiceInstancesRequest sIRequest =
179 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
181 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
183 String uri = (String) execution.getVariable(BBConstants.G_URI);
184 boolean isResume = isUriResume(uri);
186 final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
187 Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
189 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
190 RequestDetails requestDetails = sIRequest.getRequestDetails();
191 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
192 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
193 WorkflowType resourceType = resource.getResourceType();
195 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
197 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
198 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
200 if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
201 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
202 if (flowsToExecute == null) {
203 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
205 } else if (isALaCarte && isResume) {
206 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
207 if (flowsToExecute == null) {
208 buildAndThrowException(execution,
209 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
212 String vnfType = (String) execution.getVariable(VNF_TYPE);
213 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
214 List<OrchestrationFlow> orchFlows =
215 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
216 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
217 final String serviceType =
218 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
220 if (orchFlows == null || orchFlows.isEmpty()) {
221 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
222 cloudOwner, serviceType);
224 Resource resourceKey = getResourceKey(sIRequest, resourceType);
225 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
226 List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(
227 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
228 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
229 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
230 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
231 .setRequestDetails(requestDetails).setExecution(execution));
233 flowsToExecute.addAll(configBuildingBlocks);
235 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
236 .collect(Collectors.toList());
238 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
239 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
240 && resourceType.equals(WorkflowType.VFMODULE)) {
241 logger.debug("Build a BB list for replacing BB modules");
242 orchFlows = getVfModuleReplaceBuildingBlocks(
243 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
244 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
245 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
246 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
247 .setRequestDetails(requestDetails).setExecution(execution));
249 for (OrchestrationFlow orchFlow : orchFlows) {
250 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
251 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
252 requestDetails, false, null, null, false);
253 flowsToExecute.add(ebb);
256 boolean foundRelated = false;
257 boolean containsService = false;
258 List<Resource> resourceList = new ArrayList<>();
259 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
260 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
261 // SERVICE-MACRO-ASSIGN will always get user params with a
263 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
264 List<Map<String, Object>> userParams =
265 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
266 for (Map<String, Object> params : userParams) {
267 if (params.containsKey(USERPARAMSERVICE)) {
268 containsService = true;
271 if (containsService) {
272 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
275 buildAndThrowException(execution,
276 "Service-Macro-Assign request details must contain user params with a service");
278 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
279 // SERVICE-MACRO-CREATE will get user params with a service,
280 // a service with a network, a service with a
281 // networkcollection, OR an empty service.
282 // If user params is just a service or null and macro
283 // queries the SI and finds a VNF, macro fails.
285 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
286 List<Map<String, Object>> userParams =
287 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
288 for (Map<String, Object> params : userParams) {
289 if (params.containsKey(USERPARAMSERVICE)) {
290 containsService = true;
294 if (containsService) {
295 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
298 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
300 } else if (resourceType == WorkflowType.SERVICE
301 && ("activateInstance".equalsIgnoreCase(requestAction)
302 || "unassignInstance".equalsIgnoreCase(requestAction)
303 || "deleteInstance".equalsIgnoreCase(requestAction)
304 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
305 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
306 // SERVICE-MACRO-DELETE
307 // Will never get user params with service, macro will have
308 // to query the SI in AAI to find related instances.
309 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
310 } else if (resourceType == WorkflowType.SERVICE
311 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
312 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
313 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
314 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
315 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
316 workflowResourceIds.getVnfId(), aaiResourceIds);
318 buildAndThrowException(execution, "Current Macro Request is not supported");
320 String foundObjects = "";
321 for (WorkflowType type : WorkflowType.values()) {
322 foundObjects = foundObjects + type + " - " + resourceList.stream()
323 .filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size()
326 logger.info("Found {}", foundObjects);
328 if (orchFlows == null || orchFlows.isEmpty()) {
329 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
330 cloudOwner, serviceType);
332 boolean vnfReplace = false;
333 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
334 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
337 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
338 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
339 if (isNetworkCollectionInTheResourceList(resourceList)) {
340 logger.info("Sorting for Vlan Tagging");
341 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
343 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
344 if (resourceType == WorkflowType.SERVICE
345 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
346 && !resourceList.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType()))
347 .collect(Collectors.toList()).isEmpty()) {
348 execution.setVariable("homing", true);
349 execution.setVariable("calledHoming", false);
351 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
352 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
353 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
355 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
360 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
362 if (sIRequest.getRequestDetails().getRequestParameters() != null
363 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
364 List<Map<String, Object>> userParams =
365 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
366 for (Map<String, Object> params : userParams) {
367 if (params.containsKey(HOMINGSOLUTION)) {
368 if ("none".equals(params.get(HOMINGSOLUTION))) {
369 execution.setVariable("homing", false);
371 execution.setVariable("homing", true);
377 if (CollectionUtils.isEmpty(flowsToExecute)) {
378 throw new IllegalStateException("Macro did not come up with a valid execution path.");
381 List<String> flowNames = new ArrayList<>();
382 logger.info("List of BuildingBlocks to execute:");
384 flowsToExecute.forEach(ebb -> {
385 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
386 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
390 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
392 execution.setVariable("flowNames", flowNames);
393 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
394 execution.setVariable("retryCount", 0);
395 execution.setVariable("isRollback", false);
396 execution.setVariable("flowsToExecute", flowsToExecute);
397 execution.setVariable("isRollbackComplete", false);
399 } catch (Exception ex) {
400 if (!(execution.hasVariable("WorkflowException")
401 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
402 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
409 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
410 String resourceId = "";
411 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
412 if (modelInfo != null) {
413 if (modelInfo.getModelType().equals(ModelType.service)) {
414 resourceId = modelInfo.getModelVersionId();
416 resourceId = modelInfo.getModelCustomizationId();
419 return new Resource(resourceType, resourceId, true);
422 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
423 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
424 return cloudConfiguration.getCloudOwner();
426 logger.warn("cloud owner value not found in request details, it will be set as default");
427 return environment.getProperty(defaultCloudOwner);
430 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
431 AAIObjectType type) {
432 List<T> vnfcs = new ArrayList<>();
433 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
434 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
435 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
436 if (!relationshipsOp.isPresent()) {
437 logger.debug("No relationships were found for vfModule in AAI");
439 Relationships relationships = relationshipsOp.get();
440 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
441 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
442 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
443 vnfcOp.ifPresent(vnfcs::add);
449 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
451 List<T> configurations = new ArrayList<>();
452 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
453 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
454 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
455 if (!relationshipsOp.isPresent()) {
456 logger.debug("No relationships were found for VNFC in AAI");
458 Relationships relationships = relationshipsOp.get();
459 List<AAIResultWrapper> configurationResultWrappers =
460 this.getResultWrappersFromRelationships(relationships, type);
461 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
462 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
463 configurationOp.ifPresent(configurations::add);
466 return configurations;
469 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
470 AAIObjectType type) {
471 return relationships.getByType(type);
474 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
475 for (OrchestrationFlow flow : orchFlows) {
476 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
483 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
486 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
487 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
488 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
489 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
490 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
492 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
493 String vfModuleCustomizationUUID = "";
494 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
496 if (aaiVfModule == null) {
497 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
499 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
500 + vnfId + " and vfModuleId : " + vfModuleId);
502 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
505 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
506 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
507 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
508 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
509 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
510 if (configurations.size() > 1) {
511 String multipleRelationshipsError =
512 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
513 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
514 new Exception(multipleRelationshipsError));
516 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
517 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
518 for (OrchestrationFlow orchFlow : result) {
519 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
520 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
521 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
522 String vnfcName = getVnfcNameForConfiguration(configuration);
523 if (vnfcName == null || vnfcName.isEmpty()) {
524 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
525 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
526 new Exception("Vnfc and Configuration do not match"));
528 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
529 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
530 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
531 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
532 flowsToExecuteConfigs.add(ebb);
536 return flowsToExecuteConfigs;
539 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
542 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
543 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
545 logger.debug("BUILDING REPLACE LIST");
547 boolean volumeGroupExisted = false;
548 boolean volumeGroupWillExist = false;
549 boolean keepVolumeGroup = false;
551 boolean rebuildVolumeGroups = false;
552 if (dataObj.getRequestDetails().getRequestParameters() != null
553 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
554 rebuildVolumeGroups =
555 dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups().booleanValue();
558 Optional<VolumeGroup> volumeGroupFromVfModule =
559 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
560 if (volumeGroupFromVfModule.isPresent()) {
561 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
562 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
563 volumeGroupExisted = true;
564 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
567 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
568 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
569 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
570 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
571 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
572 && vfModuleCustomization.getVolumeHeatEnv() != null) {
573 volumeGroupWillExist = true;
574 if (!volumeGroupExisted) {
575 String newVolumeGroupId = UUID.randomUUID().toString();
576 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
577 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
581 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
582 keepVolumeGroup = true;
585 if (!volumeGroupExisted || keepVolumeGroup) {
586 logger.debug("Filtering out deletion of volume groups");
587 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
588 .collect(Collectors.toList());
590 if (!volumeGroupWillExist || keepVolumeGroup) {
591 logger.debug("Filtering out creation of volume groups");
592 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
593 .collect(Collectors.toList());
599 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
600 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
601 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
602 if (!relationshipsOp.isPresent()) {
603 logger.debug("No relationships were found for Configuration in AAI");
606 Relationships relationships = relationshipsOp.get();
607 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
608 if (vnfcResultWrappers.size() > 1 || vnfcResultWrappers.isEmpty()) {
609 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
611 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
612 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
616 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
618 for (Resource resource : vfModuleResources) {
619 if (resource.isBaseVfModule()) {
620 Collections.swap(vfModuleResources, 0, count);
625 return vfModuleResources;
628 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
630 for (Resource resource : vfModuleResources) {
631 if (resource.isBaseVfModule()) {
632 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
637 return vfModuleResources;
640 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
641 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
642 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
643 logger.debug(pair.getValue0() + ", " + pair.getValue1());
646 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
647 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
648 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
649 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId));
653 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
655 for (int i = 0; i < aaiResourceIds.size(); i++) {
656 if (aaiResourceIds.get(i).getValue0() == resource) {
657 id = aaiResourceIds.get(i).getValue1();
658 aaiResourceIds.remove(i);
665 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
666 String serviceInstanceId) {
667 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
668 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
669 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null,
670 resource.getVirtualLinkKey(), serviceInstanceId));
674 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
675 String key, String id, String virtualLinkKey, String serviceInstanceId) {
676 String resourceId = id;
677 if (resourceId == null) {
678 resourceId = UUID.randomUUID().toString();
680 for (ExecuteBuildingBlock ebb : flowsToExecute) {
681 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
682 .getBpmnFlowName().contains(resourceType.toString())
683 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
684 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
685 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
686 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
687 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
688 ebb.setWorkflowResourceIds(workflowResourceIds);
690 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
691 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
692 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
693 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
694 workflowResourceIds.setNetworkId(resourceId);
695 ebb.setWorkflowResourceIds(workflowResourceIds);
700 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
701 org.onap.so.db.catalog.beans.Service service) {
702 CollectionResourceCustomization networkCollection = null;
704 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
705 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
706 collectionCust.getModelCustomizationUUID()) != null) {
707 networkCollection = collectionCust;
713 } else if (count > 1) {
714 buildAndThrowException(execution,
715 "Found multiple Network Collections in the Service model, only one per Service is supported.");
717 return networkCollection;
720 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
721 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
722 throws JsonProcessingException, VrfBondingServiceException {
723 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
724 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
725 if (service == null) {
726 buildAndThrowException(execution, "Could not find the service model in catalog db.");
728 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
729 RelatedInstance relatedVpnBinding =
730 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
731 RelatedInstance relatedLocalNetwork =
732 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
733 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
734 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
736 traverseNetworkCollection(execution, resourceList, service);
741 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
742 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
743 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
744 throws VrfBondingServiceException, JsonProcessingException {
745 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
746 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
747 vrfValidation.vrfServiceValidation(service);
748 vrfValidation.vrfCatalogDbChecks(service);
749 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
750 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
751 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
752 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
753 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
754 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
755 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
756 if (existingAAIVrfConfiguration != null) {
757 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
759 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
760 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
764 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
765 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
766 throws JsonProcessingException, VrfBondingServiceException {
767 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
768 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
769 if (relationshipsOp.isPresent()) {
770 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
771 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
772 if (configurationsRelatedToLocalNetwork.size() > 1) {
773 throw new VrfBondingServiceException(
774 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
776 if (configurationsRelatedToLocalNetwork.size() == 1) {
777 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
778 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
779 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
780 relatedConfiguration.get(), configWrapper)) {
781 return relatedConfiguration.get().getConfigurationId();
788 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
789 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
790 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
791 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
792 if (relationshipsConfigOp.isPresent()) {
793 Optional<VpnBinding> relatedInfraVpnBindingOp =
794 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
795 if (relatedInfraVpnBindingOp.isPresent()) {
796 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
797 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
798 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
799 + " is not connected to the same vpn binding id provided in request: "
800 + relatedVpnBinding.getInstanceId());
810 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
811 org.onap.so.db.catalog.beans.Service service) {
812 if (isVnfCustomizationsInTheService(service)) {
813 buildAndThrowException(execution,
814 "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");
816 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
817 if (customizations.isEmpty()) {
818 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
820 CollectionResourceCustomization collectionResourceCustomization =
821 findCatalogNetworkCollection(execution, service);
822 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
824 traverseNetworkCollectionCustomization(resourceList, service);
827 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
828 CollectionResourceCustomization collectionResourceCustomization) {
829 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
832 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
833 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
834 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
835 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
836 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
837 .getCollectionInstanceGroupCustomizations()) {
838 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
839 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
840 collectionInstCust = collectionInstanceGroupTemp;
844 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
845 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
848 logger.debug("minNetworks: {}", minNetworks);
849 CollectionNetworkResourceCustomization collectionNetworkResourceCust =
850 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
851 for (int i = 0; i < minNetworks; i++) {
852 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
853 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
854 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
855 resource.setVirtualLinkKey(Integer.toString(i));
856 resourceList.add(resource);
861 private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
862 CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
863 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
864 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
865 .getCollectionNetworkResourceCustomizations()) {
866 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
867 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
868 collectionNetworkResourceCust = collectionNetworkTemp;
872 return collectionNetworkResourceCust;
875 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
876 CollectionResourceCustomization collectionResourceCustomization) {
877 if (collectionResourceCustomization == null) {
878 logger.debug("No Network Collection Customization found");
881 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
882 collectionResourceCustomization.getModelCustomizationUUID(), false));
883 logger.debug("Found a network collection");
884 if (collectionResourceCustomization.getCollectionResource() == null) {
885 logger.debug("No Network Collection found. collectionResource is null");
888 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
889 logger.debug("No Instance Group found for network collection.");
892 String toscaNodeType =
893 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
894 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
895 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
901 private boolean interfaceNetworkQuantityIsAvailableInCollection(
902 CollectionResourceInstanceGroupCustomization collectionInstCust) {
903 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
906 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
907 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
910 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
911 org.onap.so.db.catalog.beans.Service service) {
912 if (isNetworkCollectionInTheResourceList(resourceList)) {
915 if (service.getNetworkCustomizations() == null) {
916 logger.debug("No networks were found on this service model");
919 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
920 resourceList.add(new Resource(WorkflowType.NETWORK,
921 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
925 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
926 return !(resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
927 .collect(Collectors.toList()).isEmpty());
930 private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
931 return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
934 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
935 List<Pair<WorkflowType, String>> aaiResourceIds) {
937 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
938 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
939 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
940 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
941 if (serviceInstanceMSO.getVnfs() != null) {
942 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
943 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
944 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
945 if (vnf.getVfModules() != null) {
946 for (VfModule vfModule : vnf.getVfModules()) {
947 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
948 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
949 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
950 resourceList.add(resource);
953 if (vnf.getVolumeGroups() != null) {
954 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
955 .getVolumeGroups()) {
956 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
958 .add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
963 if (serviceInstanceMSO.getNetworks() != null) {
964 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
966 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
967 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
970 if (serviceInstanceMSO.getCollection() != null) {
971 logger.debug("found networkcollection");
973 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
974 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
975 serviceInstanceMSO.getCollection().getId(), false));
977 if (serviceInstanceMSO.getConfigurations() != null) {
978 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
979 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
980 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
981 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
982 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
983 if (relationship.getRelatedTo().contains("vnfc")
984 || relationship.getRelatedTo().contains("vpn-binding")) {
985 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
987 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
994 } catch (Exception ex) {
995 logger.error("Exception in traverseAAIService", ex);
996 buildAndThrowException(execution,
997 "Could not find existing Service Instance or related Instances to execute the request on.");
1001 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1002 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1004 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1005 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1006 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1007 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1008 if (serviceInstanceMSO.getVnfs() != null) {
1009 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1010 if (vnf.getVnfId().equals(vnfId)) {
1011 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1012 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1013 if (vnf.getVfModules() != null) {
1014 for (VfModule vfModule : vnf.getVfModules()) {
1015 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1016 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1017 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1018 resourceList, aaiResourceIds);
1021 if (vnf.getVolumeGroups() != null) {
1022 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1023 .getVolumeGroups()) {
1025 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1027 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1034 } catch (Exception ex) {
1035 logger.error("Exception in traverseAAIVnf", ex);
1036 buildAndThrowException(execution,
1037 "Could not find existing Vnf or related Instances to execute the request on.");
1041 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1042 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1044 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1045 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1046 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1047 Optional<Relationships> relationshipsOp;
1048 relationshipsOp = vfModuleWrapper.getRelationships();
1049 if (relationshipsOp.isPresent()) {
1050 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1051 if (relationshipsOp.isPresent()) {
1052 Optional<Configuration> config =
1053 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1054 if (config.isPresent()) {
1055 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1057 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1061 } catch (Exception ex) {
1062 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1063 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1067 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1068 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1069 boolean foundRelated = false;
1070 boolean foundVfModuleOrVG = false;
1071 String vnfCustomizationUUID = "";
1072 String vfModuleCustomizationUUID = "";
1073 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1074 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1075 for (Map<String, Object> params : userParams) {
1076 if (params.containsKey(USERPARAMSERVICE)) {
1077 ObjectMapper obj = new ObjectMapper();
1078 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1079 Service validate = obj.readValue(input, Service.class);
1081 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1082 if (validate.getResources().getVnfs() != null) {
1083 for (Vnfs vnf : validate.getResources().getVnfs()) {
1084 resourceList.add(new Resource(WorkflowType.VNF,
1085 vnf.getModelInfo().getModelCustomizationId(), false));
1086 foundRelated = true;
1087 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1088 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1090 if (vnf.getVfModules() != null) {
1091 for (VfModules vfModule : vnf.getVfModules()) {
1092 VfModuleCustomization vfModuleCustomization =
1093 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1094 vfModule.getModelInfo().getModelCustomizationUuid());
1095 if (vfModuleCustomization != null) {
1097 if (vfModuleCustomization.getVfModule() != null
1098 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1099 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1100 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1101 vfModuleCustomization.getModelCustomizationUUID(), false));
1102 foundRelated = true;
1103 foundVfModuleOrVG = true;
1106 if (vfModuleCustomization.getVfModule() != null
1107 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1108 && vfModuleCustomization.getHeatEnvironment() != null) {
1109 foundRelated = true;
1110 foundVfModuleOrVG = true;
1111 Resource resource = new Resource(WorkflowType.VFMODULE,
1112 vfModuleCustomization.getModelCustomizationUUID(), false);
1113 if (vfModuleCustomization.getVfModule().getIsBase() != null
1114 && vfModuleCustomization.getVfModule().getIsBase()) {
1115 resource.setBaseVfModule(true);
1117 resource.setBaseVfModule(false);
1119 resourceList.add(resource);
1120 if (vfModule.getModelInfo() != null
1121 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1122 vfModuleCustomizationUUID =
1123 vfModule.getModelInfo().getModelCustomizationUuid();
1125 if (!vnfCustomizationUUID.isEmpty()
1126 && !vfModuleCustomizationUUID.isEmpty()) {
1127 List<CvnfcConfigurationCustomization> configs =
1128 traverseCatalogDbForConfiguration(
1129 validate.getModelInfo().getModelVersionId(),
1130 vnfCustomizationUUID, vfModuleCustomizationUUID);
1131 for (CvnfcConfigurationCustomization config : configs) {
1132 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1133 config.getConfigurationResource().getModelUUID(), false);
1134 resource.setVnfCustomizationId(
1135 vnf.getModelInfo().getModelCustomizationId());
1136 resource.setVfModuleCustomizationId(
1137 vfModule.getModelInfo().getModelCustomizationId());
1138 resourceList.add(configResource);
1142 if (!foundVfModuleOrVG) {
1143 buildAndThrowException(execution,
1144 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1151 if (validate.getResources().getPnfs() != null) {
1152 for (Pnfs pnf : validate.getResources().getPnfs()) {
1153 resourceList.add(new Resource(WorkflowType.PNF,
1154 pnf.getModelInfo().getModelCustomizationId(), false));
1155 foundRelated = true;
1158 if (validate.getResources().getNetworks() != null) {
1159 for (Networks network : validate.getResources().getNetworks()) {
1160 resourceList.add(new Resource(WorkflowType.NETWORK,
1161 network.getModelInfo().getModelCustomizationId(), false));
1162 foundRelated = true;
1164 if (requestAction.equals(CREATEINSTANCE)) {
1165 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1166 if (networkColCustId != null) {
1167 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1168 foundRelated = true;
1176 return foundRelated;
1179 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1180 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1181 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1183 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1184 vnfCustomizationUUID, vfModuleCustomizationUUID);
1185 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1186 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1187 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1188 configurations.add(customization);
1192 logger.debug("found {} fabric configuration(s)", configurations.size());
1193 return configurations;
1194 } catch (Exception ex) {
1195 logger.error("Error in finding configurations", ex);
1196 return configurations;
1200 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1201 ServiceInstancesRequest sIRequest) {
1202 org.onap.so.db.catalog.beans.Service service =
1203 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1204 if (service != null) {
1205 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1206 if (networkCollection != null) {
1207 return networkCollection.getModelCustomizationUUID();
1213 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1214 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1217 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1218 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1219 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1220 Matcher m = patt.matcher(uri);
1221 boolean generated = false;
1224 logger.debug("found match on {} : {} ", uri, m);
1225 String type = m.group("type");
1226 String id = m.group("id");
1227 String action = m.group("action");
1229 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1231 if (action == null) {
1232 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1233 id = UUID.randomUUID().toString();
1235 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1236 id = UUID.randomUUID().toString();
1240 if (action.matches(SUPPORTEDTYPES)) {
1241 id = UUID.randomUUID().toString();
1246 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1248 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1252 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1253 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1255 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1256 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1257 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1258 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1259 workflowResourceIds);
1260 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1261 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1262 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1263 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1264 workflowResourceIds);
1265 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1266 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1267 workflowResourceIds);
1268 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1269 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1270 workflowResourceIds);
1272 return generatedResourceId;
1273 } catch (DuplicateNameException dne) {
1275 } catch (Exception ex) {
1276 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1277 throw new IllegalStateException(
1278 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1282 protected String convertTypeFromPlural(String type) {
1283 if (!type.matches(SUPPORTEDTYPES)) {
1286 if (type.equals(SERVICE_INSTANCES)) {
1289 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1294 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1295 String requestAction) {
1296 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1297 if (requestAction.equals(CREATEINSTANCE)) {
1298 for (ExecuteBuildingBlock ebb : orchFlows) {
1299 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1300 String key = ebb.getBuildingBlock().getKey();
1301 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1302 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1303 sortedOrchFlows.add(ebb);
1304 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1305 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1306 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1307 sortedOrchFlows.add(ebb2);
1310 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1311 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1312 sortedOrchFlows.add(ebb2);
1316 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1317 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1318 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1319 sortedOrchFlows.add(ebb2);
1322 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1323 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1324 sortedOrchFlows.add(ebb2);
1328 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1329 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1331 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1332 sortedOrchFlows.add(ebb);
1335 } else if (requestAction.equals("deleteInstance")) {
1336 for (ExecuteBuildingBlock ebb : orchFlows) {
1337 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1338 sortedOrchFlows.add(ebb);
1339 String key = ebb.getBuildingBlock().getKey();
1340 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1341 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1342 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1343 sortedOrchFlows.add(ebb2);
1347 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1348 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1349 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1350 sortedOrchFlows.add(ebb2);
1354 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1355 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1357 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1358 sortedOrchFlows.add(ebb);
1362 return sortedOrchFlows;
1365 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1366 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1367 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1368 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1370 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1371 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1372 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1373 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1376 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1377 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1378 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1379 boolean replaceVnf) {
1380 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1381 for (OrchestrationFlow orchFlow : orchFlows) {
1382 if (orchFlow.getFlowName().contains(SERVICE)) {
1384 workflowResourceIds.setServiceInstanceId(resourceId);
1386 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1387 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1389 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1390 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1391 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1392 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1394 } else if (orchFlow.getFlowName().contains(PNF)) {
1395 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1396 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1398 } else if (orchFlow.getFlowName().contains(NETWORK)
1399 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1400 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1401 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1403 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1404 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1406 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1407 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1408 List<Resource> vfModuleResourcesSorted = null;
1409 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1410 || requestAction.equals("activateInstance")) {
1411 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1412 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1414 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1415 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1417 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
1418 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i),
1419 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1420 false, null, null, false));
1422 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1423 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1424 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1425 logger.debug("Replacing workflow resource id by volume group id");
1426 resourceId = workflowResourceIds.getVolumeGroupId();
1428 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1429 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1431 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1432 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1433 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1435 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1436 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1437 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1440 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1441 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1444 return flowsToExecute;
1447 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1448 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1449 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1450 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1452 BuildingBlock buildingBlock =
1453 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1454 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1455 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1456 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(action -> buildingBlock.setBpmnAction(action));
1457 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(scope -> buildingBlock.setBpmnScope(scope));
1459 if (resource != null
1460 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1461 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1462 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1463 resourceId = workflowResourceIds.getVolumeGroupId();
1466 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1467 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1468 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1469 .setRequestDetails(requestDetails);
1471 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1472 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1473 Optional.ofNullable(vnfcName).ifPresent(name -> configurationResourceKeys.setVnfcName(name));
1474 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1475 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1476 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1477 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1479 return executeBuildingBlock;
1482 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1483 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1484 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1487 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1488 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1489 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1490 NorthBoundRequest northBoundRequest = null;
1491 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1492 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1494 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1495 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1497 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1498 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1500 if (northBoundRequest == null) {
1501 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1502 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1504 if (northBoundRequest == null) {
1505 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1506 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1508 if (northBoundRequest.getIsToplevelflow() != null) {
1509 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1511 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1513 flows = new ArrayList<>();
1514 for (OrchestrationFlow flow : flows) {
1515 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1516 List<OrchestrationFlow> macroQueryFlows =
1517 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1518 listToExecute.addAll(macroQueryFlows);
1520 listToExecute.add(flow);
1524 return listToExecute;
1527 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1528 logger.error(msg, ex);
1529 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1530 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1533 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1535 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1536 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1539 public void handleRuntimeException(DelegateExecution execution) {
1540 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1541 String runtimeErrorMessage;
1543 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1544 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1545 wfeExpMsg.append(": ").append(javaExpMsg);
1547 runtimeErrorMessage = wfeExpMsg.toString();
1548 logger.error(runtimeErrorMessage);
1549 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1550 } catch (Exception e) {
1551 logger.error("Runtime error", e);
1552 // if runtime message was mulformed
1553 runtimeErrorMessage = "Runtime error";
1555 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1558 protected boolean isUriResume(String uri) {
1559 return uri.endsWith("/resume");
1562 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1563 String serviceInstanceId) {
1564 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1565 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1566 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1567 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1570 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1571 RequestDetails reqDetails) throws DuplicateNameException, MultipleObjectsFoundException {
1572 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1573 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1574 if (instanceName != null) {
1575 Optional<ServiceInstance> serviceInstanceAAI =
1576 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1577 if (serviceInstanceAAI.isPresent()) {
1578 if (serviceInstanceAAI.get().getModelVersionId()
1579 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1580 return serviceInstanceAAI.get().getServiceInstanceId();
1582 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1583 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1586 ServiceInstances aaiServiceInstances =
1587 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1588 if (aaiServiceInstances != null) {
1589 if (aaiServiceInstances.getServiceInstance() != null
1590 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1591 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1592 throw new DuplicateNameException(SERVICE_INSTANCE,
1593 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1595 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1596 Map<String, String> keys =
1597 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1599 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1600 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1601 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1603 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1604 si.getModelVersionId()));
1610 return generatedResourceId;
1613 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1614 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1615 throws DuplicateNameException, MultipleObjectsFoundException {
1616 Optional<L3Network> network = bbInputSetupUtils
1617 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1618 if (network.isPresent()) {
1619 if (network.get().getModelCustomizationId()
1620 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1621 return network.get().getNetworkId();
1623 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1624 instanceName, network.get().getModelCustomizationId()));
1627 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1628 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1629 workflowResourceIds.getServiceInstanceId()));
1631 return generatedResourceId;
1634 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1635 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1636 throws DuplicateNameException, MultipleObjectsFoundException {
1637 Optional<GenericVnf> vnf = bbInputSetupUtils
1638 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1639 if (vnf.isPresent()) {
1640 if (vnf.get().getModelCustomizationId()
1641 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1642 return vnf.get().getVnfId();
1644 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1645 instanceName, vnf.get().getModelCustomizationId()));
1648 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1650 throw new DuplicateNameException("generic-vnf",
1651 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1653 return generatedResourceId;
1656 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1657 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1658 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1659 if (vnf != null && vnf.getVfModules() != null) {
1660 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1661 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1662 if (vfModule.getModelCustomizationId()
1663 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1664 return vfModule.getVfModuleId();
1666 throw new DuplicateNameException("vfModule",
1667 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1668 reqDetails.getModelInfo().getModelCustomizationId()));
1673 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1674 throw new DuplicateNameException("vfModule", instanceName);
1676 return generatedResourceId;
1679 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1680 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1681 throws DuplicateNameException, MultipleObjectsFoundException {
1682 Optional<VolumeGroup> volumeGroup =
1683 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1684 if (volumeGroup.isPresent()) {
1685 if (volumeGroup.get().getVfModuleModelCustomizationId()
1686 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1687 return volumeGroup.get().getVolumeGroupId();
1689 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1692 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1693 throw new DuplicateNameException("volumeGroup", instanceName);
1695 return generatedResourceId;
1698 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1699 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1700 throws DuplicateNameException, MultipleObjectsFoundException {
1701 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1702 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1703 workflowResourceIds.getServiceInstanceId(), instanceName);
1704 if (configuration.isPresent()) {
1705 if (configuration.get().getModelCustomizationId()
1706 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1707 return configuration.get().getConfigurationId();
1709 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1710 instanceName, configuration.get().getConfigurationId()));
1713 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1714 throw new DuplicateNameException("configuration", instanceName);
1716 return generatedResourceId;
1719 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1720 WorkflowType resourceType) {
1721 execution.setVariable("sentSyncResponse", false);
1722 execution.setVariable("homing", false);
1723 execution.setVariable("calledHoming", false);
1724 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1725 execution.setVariable("suppressRollback", suppressRollback);
1726 execution.setVariable("resourceId", resourceId);
1727 execution.setVariable("resourceType", resourceType);
1728 execution.setVariable("resourceName", resourceType.toString());
1731 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1733 if (!alaCarte && isResume) {
1734 logger.debug("replacing URI {}", uri);
1735 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1736 logger.debug("for RESUME with original value {}", uri);
1738 return extractResourceIdAndTypeFromUri(uri);
1741 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1742 WorkflowResourceIds workflowResourceIds) throws Exception {
1743 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1744 && requestDetails.getRequestInfo().getInstanceName() != null) {
1745 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1746 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1748 return resource.getResourceId();
1752 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1753 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1754 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1755 serviceInstanceId = resourceId;
1757 return serviceInstanceId;