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