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 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 * ============LICENSE_END=========================================================
25 package org.onap.so.bpmn.infrastructure.workflow.tasks;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.List;
33 import java.util.Optional;
34 import java.util.UUID;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37 import java.util.stream.Collectors;
38 import org.camunda.bpm.engine.delegate.DelegateExecution;
39 import org.javatuples.Pair;
40 import org.onap.aai.domain.yang.GenericVnf;
41 import org.onap.aai.domain.yang.GenericVnfs;
42 import org.onap.aai.domain.yang.L3Network;
43 import org.onap.aai.domain.yang.Relationship;
44 import org.onap.aai.domain.yang.ServiceInstance;
45 import org.onap.aai.domain.yang.ServiceInstances;
46 import org.onap.aai.domain.yang.Vnfc;
47 import org.onap.aai.domain.yang.VolumeGroup;
48 import org.onap.aai.domain.yang.VpnBinding;
49 import org.onap.so.bpmn.common.BBConstants;
50 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
51 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
52 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
53 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
54 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
55 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
56 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
57 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
58 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
59 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
60 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
61 import org.onap.so.client.aai.AAICommonObjectMapperProvider;
62 import org.onap.so.client.aai.AAIObjectType;
63 import org.onap.so.client.aai.entities.AAIResultWrapper;
64 import org.onap.so.client.aai.entities.Relationships;
65 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
66 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
67 import org.onap.so.client.exception.ExceptionBuilder;
68 import org.onap.so.client.orchestration.AAIConfigurationResources;
69 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
70 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
71 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
72 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
73 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
74 import org.onap.so.db.catalog.beans.CvnfcCustomization;
75 import org.onap.so.db.catalog.beans.VfModuleCustomization;
76 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
77 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
78 import org.onap.so.db.catalog.client.CatalogDbClient;
79 import org.onap.so.serviceinstancebeans.CloudConfiguration;
80 import org.onap.so.serviceinstancebeans.ModelInfo;
81 import org.onap.so.serviceinstancebeans.ModelType;
82 import org.onap.so.serviceinstancebeans.Networks;
83 import org.onap.so.serviceinstancebeans.Pnfs;
84 import org.onap.so.serviceinstancebeans.RelatedInstance;
85 import org.onap.so.serviceinstancebeans.RequestDetails;
86 import org.onap.so.serviceinstancebeans.RequestInfo;
87 import org.onap.so.serviceinstancebeans.Service;
88 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
89 import org.onap.so.serviceinstancebeans.VfModules;
90 import org.onap.so.serviceinstancebeans.Vnfs;
91 import org.slf4j.Logger;
92 import org.slf4j.LoggerFactory;
93 import org.springframework.beans.factory.annotation.Autowired;
94 import org.springframework.core.env.Environment;
95 import org.springframework.stereotype.Component;
96 import com.fasterxml.jackson.core.JsonProcessingException;
97 import com.fasterxml.jackson.databind.ObjectMapper;
98 import org.springframework.util.CollectionUtils;
101 public class WorkflowAction {
103 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
104 private static final String SERVICE_INSTANCES = "serviceInstances";
105 private static final String SERVICE_INSTANCE = "serviceInstance";
106 private static final String VF_MODULES = "vfModules";
107 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
108 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
109 private static final String VNF_TYPE = "vnfType";
110 private static final String SERVICE = "Service";
111 private static final String VNF = "Vnf";
112 private static final String PNF = "Pnf";
113 private static final String VFMODULE = "VfModule";
114 private static final String VOLUMEGROUP = "VolumeGroup";
115 private static final String NETWORK = "Network";
116 private static final String NETWORKCOLLECTION = "NetworkCollection";
117 private static final String CONFIGURATION = "Configuration";
118 private static final String ASSIGNINSTANCE = "assignInstance";
119 private static final String CREATEINSTANCE = "createInstance";
120 private static final String REPLACEINSTANCE = "replaceInstance";
121 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
122 private static final String USERPARAMSERVICE = "service";
123 private static final String SUPPORTEDTYPES =
124 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
125 private static final String HOMINGSOLUTION = "Homing_Solution";
126 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
127 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
128 private static final String SERVICE_TYPE_BONDING = "BONDING";
129 private static final String CLOUD_OWNER = "DEFAULT";
130 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
131 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
132 private static final String NAME_EXISTS_MULTIPLE =
133 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
134 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
135 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
136 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
137 "(%s), same parent and different customization id (%s)";
138 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
139 private static final String CREATENETWORKBB = "CreateNetworkBB";
140 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
141 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
142 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
145 protected BBInputSetup bbInputSetup;
147 protected BBInputSetupUtils bbInputSetupUtils;
149 private ExceptionBuilder exceptionBuilder;
151 private CatalogDbClient catalogDbClient;
153 private AAIConfigurationResources aaiConfigurationResources;
155 private WorkflowActionExtractResourcesAAI workflowActionUtils;
157 private VrfValidation vrfValidation;
160 private Environment environment;
161 private String defaultCloudOwner = "org.onap.so.cloud-owner";
163 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
164 this.bbInputSetupUtils = bbInputSetupUtils;
167 public void setBbInputSetup(BBInputSetup bbInputSetup) {
168 this.bbInputSetup = bbInputSetup;
171 public void selectExecutionList(DelegateExecution execution) throws Exception {
172 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
173 final String vnfType = (String) execution.getVariable(VNF_TYPE);
174 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
175 final String createInstanceAction = "createInstance";
176 final String serviceType =
177 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
179 List<OrchestrationFlow> orchFlows =
180 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
181 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
182 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
183 List<Resource> resourceList = new ArrayList<>();
184 execution.setVariable("sentSyncResponse", false);
185 execution.setVariable("homing", false);
186 execution.setVariable("calledHoming", false);
187 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
190 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
191 ServiceInstancesRequest sIRequest =
192 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
193 RequestDetails requestDetails = sIRequest.getRequestDetails();
194 execution.setVariable("suppressRollback", requestDetails.getRequestInfo().getSuppressRollback());
195 String uri = (String) execution.getVariable(BBConstants.G_URI);
196 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
197 final boolean aLaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
198 boolean isResume = isUriResume(uri);
199 if (!aLaCarte && isResume) {
200 logger.debug("replacing URI {}", uri);
201 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
202 logger.debug("for RESUME with original value {}", uri);
204 Resource resource = extractResourceIdAndTypeFromUri(uri);
205 WorkflowType resourceType = resource.getResourceType();
206 execution.setVariable("resourceName", resourceType.toString());
207 String resourceId = "";
208 final String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
209 if (resource.isGenerated() && requestAction.equalsIgnoreCase(createInstanceAction)
210 && sIRequest.getRequestDetails().getRequestInfo().getInstanceName() != null) {
211 resourceId = validateResourceIdInAAI(resource.getResourceId(), resourceType,
212 sIRequest.getRequestDetails().getRequestInfo().getInstanceName(), sIRequest.getRequestDetails(),
213 workflowResourceIds);
215 resourceId = resource.getResourceId();
217 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && resourceType == WorkflowType.SERVICE) {
218 serviceInstanceId = resourceId;
220 execution.setVariable("resourceId", resourceId);
221 execution.setVariable("resourceType", resourceType);
222 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
223 if (isRequestMacroServiceResume(aLaCarte, resourceType, requestAction, serviceInstanceId)) {
224 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
225 if (flowsToExecute == null) {
226 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
228 } else if (aLaCarte && isResume) {
229 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
230 if (flowsToExecute == null) {
231 buildAndThrowException(execution,
232 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
235 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
237 if (orchFlows == null || orchFlows.isEmpty()) {
238 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte,
239 cloudOwner, serviceType);
242 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
243 if (modelInfo != null) {
244 if (modelInfo.getModelType().equals(ModelType.service)) {
245 key = modelInfo.getModelVersionId();
247 key = modelInfo.getModelCustomizationId();
250 boolean isConfiguration = isConfiguration(orchFlows);
251 Resource resourceKey = new Resource(resourceType, key, aLaCarte);
252 if (isConfiguration && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
253 List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(
254 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
255 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
256 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(aLaCarte)
257 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
258 .setRequestDetails(requestDetails).setExecution(execution));
260 flowsToExecute.addAll(configBuildingBlocks);
262 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
263 .collect(Collectors.toList());
265 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
266 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
267 && resourceType.equals(WorkflowType.VFMODULE)) {
268 logger.debug("Build a BB list for replacing BB modules");
269 orchFlows = getVfModuleReplaceBuildingBlocks(
270 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
271 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
272 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(aLaCarte)
273 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
274 .setRequestDetails(requestDetails).setExecution(execution));
276 for (OrchestrationFlow orchFlow : orchFlows) {
277 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
278 apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds,
279 requestDetails, false, null, null, false);
280 flowsToExecute.add(ebb);
283 boolean foundRelated = false;
284 boolean containsService = false;
285 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
286 // SERVICE-MACRO-ASSIGN will always get user params with a
288 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
289 List<Map<String, Object>> userParams =
290 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
291 for (Map<String, Object> params : userParams) {
292 if (params.containsKey(USERPARAMSERVICE)) {
293 containsService = true;
296 if (containsService) {
297 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
300 buildAndThrowException(execution,
301 "Service-Macro-Assign request details must contain user params with a service");
303 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
304 // SERVICE-MACRO-CREATE will get user params with a service,
305 // a service with a network, a service with a
306 // networkcollection, OR an empty service.
307 // If user params is just a service or null and macro
308 // queries the SI and finds a VNF, macro fails.
310 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
311 List<Map<String, Object>> userParams =
312 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
313 for (Map<String, Object> params : userParams) {
314 if (params.containsKey(USERPARAMSERVICE)) {
315 containsService = true;
319 if (containsService) {
320 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
323 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
325 } else if (resourceType == WorkflowType.SERVICE
326 && ("activateInstance".equalsIgnoreCase(requestAction)
327 || "unassignInstance".equalsIgnoreCase(requestAction)
328 || "deleteInstance".equalsIgnoreCase(requestAction)
329 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
330 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
331 // SERVICE-MACRO-DELETE
332 // Will never get user params with service, macro will have
333 // to query the SI in AAI to find related instances.
334 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
335 } else if (resourceType == WorkflowType.SERVICE
336 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
337 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
338 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
339 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
340 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
341 workflowResourceIds.getVnfId(), aaiResourceIds);
343 buildAndThrowException(execution, "Current Macro Request is not supported");
345 String foundObjects = "";
346 for (WorkflowType type : WorkflowType.values()) {
347 foundObjects = foundObjects + type + " - " + resourceList.stream()
348 .filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size()
351 logger.info("Found {}", foundObjects);
353 if (orchFlows == null || orchFlows.isEmpty()) {
354 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte,
355 cloudOwner, serviceType);
357 boolean vnfReplace = false;
358 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
359 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
362 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
363 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
364 if (!resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
365 .collect(Collectors.toList()).isEmpty()) {
366 logger.info("Sorting for Vlan Tagging");
367 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
369 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
370 if (resourceType == WorkflowType.SERVICE
371 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
372 && !resourceList.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType()))
373 .collect(Collectors.toList()).isEmpty()) {
374 execution.setVariable("homing", true);
375 execution.setVariable("calledHoming", false);
377 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
378 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
379 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
381 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
386 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
388 if (sIRequest.getRequestDetails().getRequestParameters() != null
389 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
390 List<Map<String, Object>> userParams =
391 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
392 for (Map<String, Object> params : userParams) {
393 if (params.containsKey(HOMINGSOLUTION)) {
394 if ("none".equals(params.get(HOMINGSOLUTION))) {
395 execution.setVariable("homing", false);
397 execution.setVariable("homing", true);
403 if (CollectionUtils.isEmpty(flowsToExecute)) {
404 throw new IllegalStateException("Macro did not come up with a valid execution path.");
407 List<String> flowNames = new ArrayList<>();
408 logger.info("List of BuildingBlocks to execute:");
410 flowsToExecute.forEach(ebb -> {
411 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
412 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
416 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
418 execution.setVariable("flowNames", flowNames);
419 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
420 execution.setVariable("retryCount", 0);
421 execution.setVariable("isRollback", false);
422 execution.setVariable("flowsToExecute", flowsToExecute);
423 execution.setVariable("isRollbackComplete", false);
425 } catch (Exception ex) {
426 if (!(execution.hasVariable("WorkflowException")
427 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
428 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
435 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
436 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
437 return cloudConfiguration.getCloudOwner();
439 logger.warn("cloud owner value not found in request details, it will be set as default");
440 return environment.getProperty(defaultCloudOwner);
443 private boolean isSuppressRollback(RequestInfo requestInfo) {
444 if (requestInfo != null) {
445 return requestInfo.getSuppressRollback();
450 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
451 AAIObjectType type) {
452 List<T> vnfcs = new ArrayList<>();
453 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
454 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
455 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
456 if (!relationshipsOp.isPresent()) {
457 logger.debug("No relationships were found for vfModule in AAI");
459 Relationships relationships = relationshipsOp.get();
460 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
461 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
462 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
463 vnfcOp.ifPresent(vnfcs::add);
469 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
471 List<T> configurations = new ArrayList<>();
472 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
473 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
474 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
475 if (!relationshipsOp.isPresent()) {
476 logger.debug("No relationships were found for VNFC in AAI");
478 Relationships relationships = relationshipsOp.get();
479 List<AAIResultWrapper> configurationResultWrappers =
480 this.getResultWrappersFromRelationships(relationships, type);
481 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
482 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
483 configurationOp.ifPresent(configurations::add);
486 return configurations;
489 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
490 AAIObjectType type) {
491 return relationships.getByType(type);
494 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
495 for (OrchestrationFlow flow : orchFlows) {
496 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
503 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
506 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
507 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
508 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
509 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
510 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
512 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
513 String vfModuleCustomizationUUID = "";
514 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
516 if (aaiVfModule == null) {
517 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
519 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
520 + vnfId + " and vfModuleId : " + vfModuleId);
522 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
525 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
526 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
527 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
528 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
529 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
530 if (configurations.size() > 1) {
531 String multipleRelationshipsError =
532 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
533 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
534 new Exception(multipleRelationshipsError));
536 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
537 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
538 for (OrchestrationFlow orchFlow : result) {
539 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
540 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
541 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
542 String vnfcName = getVnfcNameForConfiguration(configuration);
543 if (vnfcName == null || vnfcName.isEmpty()) {
544 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
545 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
546 new Exception("Vnfc and Configuration do not match"));
548 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
549 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
550 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
551 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
552 flowsToExecuteConfigs.add(ebb);
556 return flowsToExecuteConfigs;
559 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
562 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
563 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
565 logger.debug("BUILDING REPLACE LIST");
567 boolean volumeGroupExisted = false;
568 boolean volumeGroupWillExist = false;
569 boolean keepVolumeGroup = false;
571 boolean rebuildVolumeGroups = false;
572 if (dataObj.getRequestDetails().getRequestParameters() != null
573 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
574 rebuildVolumeGroups =
575 dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups().booleanValue();
578 Optional<VolumeGroup> volumeGroupFromVfModule =
579 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
580 if (volumeGroupFromVfModule.isPresent()) {
581 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
582 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
583 volumeGroupExisted = true;
584 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
587 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
588 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
589 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
590 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
591 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
592 && vfModuleCustomization.getVolumeHeatEnv() != null) {
593 volumeGroupWillExist = true;
594 if (!volumeGroupExisted) {
595 String newVolumeGroupId = UUID.randomUUID().toString();
596 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
597 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
601 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
602 keepVolumeGroup = true;
605 if (!volumeGroupExisted || keepVolumeGroup) {
606 logger.debug("Filtering out deletion of volume groups");
607 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
608 .collect(Collectors.toList());
610 if (!volumeGroupWillExist || keepVolumeGroup) {
611 logger.debug("Filtering out creation of volume groups");
612 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
613 .collect(Collectors.toList());
619 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
620 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
621 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
622 if (!relationshipsOp.isPresent()) {
623 logger.debug("No relationships were found for Configuration in AAI");
626 Relationships relationships = relationshipsOp.get();
627 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
628 if (vnfcResultWrappers.size() > 1 || vnfcResultWrappers.isEmpty()) {
629 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
631 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
632 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
636 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
638 for (Resource resource : vfModuleResources) {
639 if (resource.isBaseVfModule()) {
640 Collections.swap(vfModuleResources, 0, count);
645 return vfModuleResources;
648 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
650 for (Resource resource : vfModuleResources) {
651 if (resource.isBaseVfModule()) {
652 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
657 return vfModuleResources;
660 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
661 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
662 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
663 logger.debug(pair.getValue0() + ", " + pair.getValue1());
666 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
667 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
668 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
669 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId));
673 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
675 for (int i = 0; i < aaiResourceIds.size(); i++) {
676 if (aaiResourceIds.get(i).getValue0() == resource) {
677 id = aaiResourceIds.get(i).getValue1();
678 aaiResourceIds.remove(i);
685 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
686 String serviceInstanceId) {
687 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
688 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
689 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null,
690 resource.getVirtualLinkKey(), serviceInstanceId));
694 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
695 String key, String id, String virtualLinkKey, String serviceInstanceId) {
696 String resourceId = id;
697 if (resourceId == null) {
698 resourceId = UUID.randomUUID().toString();
700 for (ExecuteBuildingBlock ebb : flowsToExecute) {
701 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey())
702 && ebb.getBuildingBlock().getBpmnFlowName().contains(resourceType.toString())) {
703 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
704 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
705 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
706 ebb.setWorkflowResourceIds(workflowResourceIds);
708 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
709 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
710 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
711 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
712 workflowResourceIds.setNetworkId(resourceId);
713 ebb.setWorkflowResourceIds(workflowResourceIds);
718 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
719 org.onap.so.db.catalog.beans.Service service) {
720 CollectionResourceCustomization networkCollection = null;
722 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
723 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
724 collectionCust.getModelCustomizationUUID()) != null) {
725 networkCollection = collectionCust;
731 } else if (count > 1) {
732 buildAndThrowException(execution,
733 "Found multiple Network Collections in the Service model, only one per Service is supported.");
735 return networkCollection;
738 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
739 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
740 throws JsonProcessingException, VrfBondingServiceException {
741 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
742 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
743 if (service == null) {
744 buildAndThrowException(execution, "Could not find the service model in catalog db.");
746 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
747 RelatedInstance relatedVpnBinding =
748 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
749 RelatedInstance relatedLocalNetwork =
750 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
751 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
752 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
754 traverseNetworkCollection(execution, resourceList, service);
759 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
760 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
761 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
762 throws VrfBondingServiceException, JsonProcessingException {
763 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
764 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
765 vrfValidation.vrfServiceValidation(service);
766 vrfValidation.vrfCatalogDbChecks(service);
767 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
768 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
769 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
770 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
771 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
772 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
773 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
774 if (existingAAIVrfConfiguration != null) {
775 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
777 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
778 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
782 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
783 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
784 throws JsonProcessingException, VrfBondingServiceException {
785 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
786 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
787 if (relationshipsOp.isPresent()) {
788 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
789 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
790 if (configurationsRelatedToLocalNetwork.size() > 1) {
791 throw new VrfBondingServiceException(
792 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
794 if (configurationsRelatedToLocalNetwork.size() == 1) {
795 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
796 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
797 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
798 relatedConfiguration.get(), configWrapper)) {
799 return relatedConfiguration.get().getConfigurationId();
806 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
807 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
808 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
809 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
810 if (relationshipsConfigOp.isPresent()) {
811 Optional<VpnBinding> relatedInfraVpnBindingOp =
812 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
813 if (relatedInfraVpnBindingOp.isPresent()) {
814 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
815 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
816 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
817 + " is not connected to the same vpn binding id provided in request: "
818 + relatedVpnBinding.getInstanceId());
828 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
829 org.onap.so.db.catalog.beans.Service service) {
830 if (service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty()) {
831 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
832 if (customizations.isEmpty()) {
833 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
835 CollectionResourceCustomization collectionResourceCustomization =
836 findCatalogNetworkCollection(execution, service);
837 if (collectionResourceCustomization != null) {
838 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
839 collectionResourceCustomization.getModelCustomizationUUID(), false));
840 logger.debug("Found a network collection");
841 if (collectionResourceCustomization.getCollectionResource() != null) {
842 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null) {
843 String toscaNodeType = collectionResourceCustomization.getCollectionResource()
844 .getInstanceGroup().getToscaNodeType();
845 if (toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION)) {
847 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
848 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
849 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
850 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
851 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
852 .getCollectionInstanceGroupCustomizations()) {
853 if (collectionInstanceGroupTemp.getModelCustomizationUUID().equalsIgnoreCase(
854 collectionResourceCustomization.getModelCustomizationUUID())) {
855 collectionInstCust = collectionInstanceGroupTemp;
859 if (collectionInstCust != null
860 && collectionInstCust.getSubInterfaceNetworkQuantity() != null) {
861 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
864 logger.debug("minNetworks: {}", minNetworks);
865 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
866 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
867 .getCollectionNetworkResourceCustomizations()) {
868 if (collectionNetworkTemp.getNetworkResourceCustomization()
869 .getModelCustomizationUUID().equalsIgnoreCase(
870 collectionResourceCustomization.getModelCustomizationUUID())) {
871 collectionNetworkResourceCust = collectionNetworkTemp;
875 for (int i = 0; i < minNetworks; i++) {
876 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
877 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
878 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
879 resource.setVirtualLinkKey(Integer.toString(i));
880 resourceList.add(resource);
884 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}",
888 logger.debug("No Instance Group found for network collection.");
891 logger.debug("No Network Collection found. collectionResource is null");
894 logger.debug("No Network Collection Customization found");
897 if (resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
898 .collect(Collectors.toList()).isEmpty()) {
899 if (service.getNetworkCustomizations() == null) {
900 logger.debug("No networks were found on this service model");
902 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
903 resourceList.add(new Resource(WorkflowType.NETWORK,
904 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
909 buildAndThrowException(execution,
910 "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");
914 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
915 List<Pair<WorkflowType, String>> aaiResourceIds) {
917 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
918 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
919 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
920 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
921 if (serviceInstanceMSO.getVnfs() != null) {
922 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
923 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
924 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
925 if (vnf.getVfModules() != null) {
926 for (VfModule vfModule : vnf.getVfModules()) {
927 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
928 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
929 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
930 resourceList.add(resource);
933 if (vnf.getVolumeGroups() != null) {
934 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
935 .getVolumeGroups()) {
936 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
938 .add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
943 if (serviceInstanceMSO.getNetworks() != null) {
944 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
946 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
947 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
950 if (serviceInstanceMSO.getCollection() != null) {
951 logger.debug("found networkcollection");
953 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
954 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
955 serviceInstanceMSO.getCollection().getId(), false));
957 if (serviceInstanceMSO.getConfigurations() != null) {
958 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
959 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
960 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
961 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
962 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
963 if (relationship.getRelatedTo().contains("vnfc")
964 || relationship.getRelatedTo().contains("vpn-binding")) {
965 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
967 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
974 } catch (Exception ex) {
975 logger.error("Exception in traverseAAIService", ex);
976 buildAndThrowException(execution,
977 "Could not find existing Service Instance or related Instances to execute the request on.");
981 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
982 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
984 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
985 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
986 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
987 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
988 if (serviceInstanceMSO.getVnfs() != null) {
989 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
990 if (vnf.getVnfId().equals(vnfId)) {
991 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
992 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
993 if (vnf.getVfModules() != null) {
994 for (VfModule vfModule : vnf.getVfModules()) {
995 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
996 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
997 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
998 resourceList, aaiResourceIds);
1001 if (vnf.getVolumeGroups() != null) {
1002 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1003 .getVolumeGroups()) {
1005 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1007 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1014 } catch (Exception ex) {
1015 logger.error("Exception in traverseAAIVnf", ex);
1016 buildAndThrowException(execution,
1017 "Could not find existing Vnf or related Instances to execute the request on.");
1021 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1022 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1024 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1025 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1026 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1027 Optional<Relationships> relationshipsOp;
1028 relationshipsOp = vfModuleWrapper.getRelationships();
1029 if (relationshipsOp.isPresent()) {
1030 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1031 if (relationshipsOp.isPresent()) {
1032 Optional<Configuration> config =
1033 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1034 if (config.isPresent()) {
1035 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1037 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1041 } catch (Exception ex) {
1042 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1043 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1047 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1048 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1049 boolean foundRelated = false;
1050 boolean foundVfModuleOrVG = false;
1051 String vnfCustomizationUUID = "";
1052 String vfModuleCustomizationUUID = "";
1053 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1054 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1055 for (Map<String, Object> params : userParams) {
1056 if (params.containsKey(USERPARAMSERVICE)) {
1057 ObjectMapper obj = new ObjectMapper();
1058 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1059 Service validate = obj.readValue(input, Service.class);
1061 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1062 if (validate.getResources().getVnfs() != null) {
1063 for (Vnfs vnf : validate.getResources().getVnfs()) {
1064 resourceList.add(new Resource(WorkflowType.VNF,
1065 vnf.getModelInfo().getModelCustomizationId(), false));
1066 foundRelated = true;
1067 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1068 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1070 if (vnf.getVfModules() != null) {
1071 for (VfModules vfModule : vnf.getVfModules()) {
1072 VfModuleCustomization vfModuleCustomization =
1073 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1074 vfModule.getModelInfo().getModelCustomizationUuid());
1075 if (vfModuleCustomization != null) {
1077 if (vfModuleCustomization.getVfModule() != null
1078 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1079 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1080 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1081 vfModuleCustomization.getModelCustomizationUUID(), false));
1082 foundRelated = true;
1083 foundVfModuleOrVG = true;
1086 if (vfModuleCustomization.getVfModule() != null
1087 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1088 && vfModuleCustomization.getHeatEnvironment() != null) {
1089 foundRelated = true;
1090 foundVfModuleOrVG = true;
1091 Resource resource = new Resource(WorkflowType.VFMODULE,
1092 vfModuleCustomization.getModelCustomizationUUID(), false);
1093 if (vfModuleCustomization.getVfModule().getIsBase() != null
1094 && vfModuleCustomization.getVfModule().getIsBase()) {
1095 resource.setBaseVfModule(true);
1097 resource.setBaseVfModule(false);
1099 resourceList.add(resource);
1100 if (vfModule.getModelInfo() != null
1101 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1102 vfModuleCustomizationUUID =
1103 vfModule.getModelInfo().getModelCustomizationUuid();
1105 if (!vnfCustomizationUUID.isEmpty()
1106 && !vfModuleCustomizationUUID.isEmpty()) {
1107 List<CvnfcConfigurationCustomization> configs =
1108 traverseCatalogDbForConfiguration(
1109 validate.getModelInfo().getModelVersionId(),
1110 vnfCustomizationUUID, vfModuleCustomizationUUID);
1111 for (CvnfcConfigurationCustomization config : configs) {
1112 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1113 config.getConfigurationResource().getModelUUID(), false);
1114 resource.setVnfCustomizationId(
1115 vnf.getModelInfo().getModelCustomizationId());
1116 resource.setVfModuleCustomizationId(
1117 vfModule.getModelInfo().getModelCustomizationId());
1118 resourceList.add(configResource);
1122 if (!foundVfModuleOrVG) {
1123 buildAndThrowException(execution,
1124 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1131 if (validate.getResources().getPnfs() != null) {
1132 for (Pnfs pnf : validate.getResources().getPnfs()) {
1133 resourceList.add(new Resource(WorkflowType.PNF,
1134 pnf.getModelInfo().getModelCustomizationId(), false));
1135 foundRelated = true;
1138 if (validate.getResources().getNetworks() != null) {
1139 for (Networks network : validate.getResources().getNetworks()) {
1140 resourceList.add(new Resource(WorkflowType.NETWORK,
1141 network.getModelInfo().getModelCustomizationId(), false));
1142 foundRelated = true;
1144 if (requestAction.equals(CREATEINSTANCE)) {
1145 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1146 if (networkColCustId != null) {
1147 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1148 foundRelated = true;
1156 return foundRelated;
1159 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1160 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1161 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1163 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1164 vnfCustomizationUUID, vfModuleCustomizationUUID);
1165 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1166 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1167 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1168 configurations.add(customization);
1172 logger.debug("found {} fabric configuration(s)", configurations.size());
1173 return configurations;
1174 } catch (Exception ex) {
1175 logger.error("Error in finding configurations", ex);
1176 return configurations;
1180 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1181 ServiceInstancesRequest sIRequest) {
1182 org.onap.so.db.catalog.beans.Service service =
1183 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1184 if (service != null) {
1185 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1186 if (networkCollection != null) {
1187 return networkCollection.getModelCustomizationUUID();
1193 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1194 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1197 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1198 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1199 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1200 Matcher m = patt.matcher(uri);
1201 boolean generated = false;
1204 logger.debug("found match on {} : {} ", uri, m);
1205 String type = m.group("type");
1206 String id = m.group("id");
1207 String action = m.group("action");
1209 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1211 if (action == null) {
1212 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1213 id = UUID.randomUUID().toString();
1215 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1216 id = UUID.randomUUID().toString();
1220 if (action.matches(SUPPORTEDTYPES)) {
1221 id = UUID.randomUUID().toString();
1226 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1228 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1232 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1233 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1235 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1236 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1237 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1238 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1239 workflowResourceIds);
1240 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1241 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1242 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1243 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1244 workflowResourceIds);
1245 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1246 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1247 workflowResourceIds);
1248 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1249 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1250 workflowResourceIds);
1252 return generatedResourceId;
1253 } catch (DuplicateNameException dne) {
1255 } catch (Exception ex) {
1256 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1257 throw new IllegalStateException(
1258 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1262 protected String convertTypeFromPlural(String type) {
1263 if (!type.matches(SUPPORTEDTYPES)) {
1266 if (type.equals(SERVICE_INSTANCES)) {
1269 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1274 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1275 String requestAction) {
1276 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1277 if (requestAction.equals(CREATEINSTANCE)) {
1278 for (ExecuteBuildingBlock ebb : orchFlows) {
1279 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1280 String key = ebb.getBuildingBlock().getKey();
1281 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1282 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1283 sortedOrchFlows.add(ebb);
1284 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1285 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1286 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1287 sortedOrchFlows.add(ebb2);
1290 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1291 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1292 sortedOrchFlows.add(ebb2);
1296 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1297 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1298 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1299 sortedOrchFlows.add(ebb2);
1302 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1303 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1304 sortedOrchFlows.add(ebb2);
1308 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1309 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1311 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1312 sortedOrchFlows.add(ebb);
1315 } else if (requestAction.equals("deleteInstance")) {
1316 for (ExecuteBuildingBlock ebb : orchFlows) {
1317 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1318 sortedOrchFlows.add(ebb);
1319 String key = ebb.getBuildingBlock().getKey();
1320 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1321 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1322 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1323 sortedOrchFlows.add(ebb2);
1327 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1328 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1329 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1330 sortedOrchFlows.add(ebb2);
1334 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1335 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1337 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1338 sortedOrchFlows.add(ebb);
1342 return sortedOrchFlows;
1345 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1346 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1347 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1348 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1350 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1351 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1352 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1353 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1356 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1357 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1358 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1359 boolean replaceVnf) {
1360 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1361 for (OrchestrationFlow orchFlow : orchFlows) {
1362 if (orchFlow.getFlowName().contains(SERVICE)) {
1364 workflowResourceIds.setServiceInstanceId(resourceId);
1366 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1367 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1369 } else if (orchFlow.getFlowName().contains(VNF)) {
1370 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1371 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1373 } else if (orchFlow.getFlowName().contains(PNF)) {
1374 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1375 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1377 } else if (orchFlow.getFlowName().contains(NETWORK)
1378 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1379 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1380 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1382 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1383 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1385 } else if (orchFlow.getFlowName().contains(VFMODULE)) {
1386 List<Resource> vfModuleResourcesSorted = null;
1387 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1388 || requestAction.equals("activateInstance")) {
1389 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1390 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1392 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1393 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1395 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
1396 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i),
1397 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1398 false, null, null, false));
1400 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1401 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1402 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1403 logger.debug("Replacing workflow resource id by volume group id");
1404 resourceId = workflowResourceIds.getVolumeGroupId();
1406 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1407 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1409 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1410 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1411 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1413 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1414 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1415 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1418 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1419 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1422 return flowsToExecute;
1425 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1426 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1427 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1428 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1430 BuildingBlock buildingBlock =
1431 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1432 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1433 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1434 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(action -> buildingBlock.setBpmnAction(action));
1435 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(scope -> buildingBlock.setBpmnScope(scope));
1437 if (resource != null
1438 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1439 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1440 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1441 resourceId = workflowResourceIds.getVolumeGroupId();
1444 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1445 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1446 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1447 .setRequestDetails(requestDetails);
1449 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1450 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1451 Optional.ofNullable(vnfcName).ifPresent(name -> configurationResourceKeys.setVnfcName(name));
1452 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1453 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1454 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1455 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1457 return executeBuildingBlock;
1460 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1461 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1462 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1465 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1466 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1467 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1468 NorthBoundRequest northBoundRequest = null;
1469 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1470 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1472 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1473 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1475 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1476 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1478 if (northBoundRequest == null) {
1479 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1480 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1482 if (northBoundRequest == null) {
1483 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1484 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1486 if (northBoundRequest.getIsToplevelflow() != null) {
1487 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1489 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1491 flows = new ArrayList<>();
1492 for (OrchestrationFlow flow : flows) {
1493 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1494 List<OrchestrationFlow> macroQueryFlows =
1495 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1496 listToExecute.addAll(macroQueryFlows);
1498 listToExecute.add(flow);
1502 return listToExecute;
1505 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1506 logger.error(msg, ex);
1507 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1508 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1511 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1513 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1514 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1517 public void handleRuntimeException(DelegateExecution execution) {
1518 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1519 String runtimeErrorMessage;
1521 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1522 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1523 wfeExpMsg.append(": ").append(javaExpMsg);
1525 runtimeErrorMessage = wfeExpMsg.toString();
1526 logger.error(runtimeErrorMessage);
1527 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1528 } catch (Exception e) {
1529 logger.error("Runtime error", e);
1530 // if runtime message was mulformed
1531 runtimeErrorMessage = "Runtime error";
1533 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1536 protected boolean isUriResume(String uri) {
1537 return uri.endsWith("/resume");
1540 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1541 String serviceInstanceId) {
1542 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1543 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1544 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1545 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1548 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1549 RequestDetails reqDetails) throws DuplicateNameException, MultipleObjectsFoundException {
1550 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1551 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1552 if (instanceName != null) {
1553 Optional<ServiceInstance> serviceInstanceAAI =
1554 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1555 if (serviceInstanceAAI.isPresent()) {
1556 if (serviceInstanceAAI.get().getModelVersionId()
1557 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1558 return serviceInstanceAAI.get().getServiceInstanceId();
1560 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1561 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1564 ServiceInstances aaiServiceInstances =
1565 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1566 if (aaiServiceInstances != null) {
1567 if (aaiServiceInstances.getServiceInstance() != null
1568 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1569 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1570 throw new DuplicateNameException(SERVICE_INSTANCE,
1571 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1573 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1574 Map<String, String> keys =
1575 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1577 throw new DuplicateNameException(SERVICE_INSTANCE,
1578 String.format(NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1579 keys.get("global-customer-id"), keys.get("service-type"),
1580 si.getModelVersionId()));
1586 return generatedResourceId;
1589 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1590 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1591 throws DuplicateNameException, MultipleObjectsFoundException {
1592 Optional<L3Network> network = bbInputSetupUtils
1593 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1594 if (network.isPresent()) {
1595 if (network.get().getModelCustomizationId()
1596 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1597 return network.get().getNetworkId();
1599 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1600 instanceName, network.get().getModelCustomizationId()));
1603 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1604 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1605 workflowResourceIds.getServiceInstanceId()));
1607 return generatedResourceId;
1610 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1611 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1612 throws DuplicateNameException, MultipleObjectsFoundException {
1613 Optional<GenericVnf> vnf = bbInputSetupUtils
1614 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1615 if (vnf.isPresent()) {
1616 if (vnf.get().getModelCustomizationId()
1617 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1618 return vnf.get().getVnfId();
1620 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1621 instanceName, vnf.get().getModelCustomizationId()));
1624 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1626 throw new DuplicateNameException("generic-vnf",
1627 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1629 return generatedResourceId;
1632 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1633 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1634 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1635 if (vnf != null && vnf.getVfModules() != null) {
1636 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1637 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1638 if (vfModule.getModelCustomizationId()
1639 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1640 return vfModule.getVfModuleId();
1642 throw new DuplicateNameException("vfModule",
1643 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1644 reqDetails.getModelInfo().getModelCustomizationId()));
1649 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1650 throw new DuplicateNameException("vfModule", instanceName);
1652 return generatedResourceId;
1655 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1656 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1657 throws DuplicateNameException, MultipleObjectsFoundException {
1658 Optional<VolumeGroup> volumeGroup =
1659 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1660 if (volumeGroup.isPresent()) {
1661 if (volumeGroup.get().getVfModuleModelCustomizationId()
1662 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1663 return volumeGroup.get().getVolumeGroupId();
1665 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1668 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1669 throw new DuplicateNameException("volumeGroup", instanceName);
1671 return generatedResourceId;
1674 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1675 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1676 throws DuplicateNameException, MultipleObjectsFoundException {
1677 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1678 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1679 workflowResourceIds.getServiceInstanceId(), instanceName);
1680 if (configuration.isPresent()) {
1681 if (configuration.get().getModelCustomizationId()
1682 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1683 return configuration.get().getConfigurationId();
1685 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1686 instanceName, configuration.get().getConfigurationId()));
1689 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1690 throw new DuplicateNameException("configuration", instanceName);
1692 return generatedResourceId;