2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.bpmn.infrastructure.aai.tasks;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.TreeSet;
27 import java.util.UUID;
28 import java.util.stream.Collectors;
30 import org.camunda.bpm.engine.delegate.BpmnError;
31 import org.onap.so.bpmn.common.BuildingBlockExecution;
32 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
33 import org.onap.so.bpmn.servicedecomposition.bbobjects.Collection;
34 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
35 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
36 import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
37 import org.onap.so.bpmn.servicedecomposition.bbobjects.InstanceGroup;
38 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.LineOfBusiness;
40 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.OwningEntity;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.Platform;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.Project;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup;
47 import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
48 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
49 import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
50 import org.onap.so.client.aai.AAIObjectPlurals;
51 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
52 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
53 import org.onap.so.client.exception.BBObjectNotFoundException;
54 import org.onap.so.client.exception.ExceptionBuilder;
55 import org.onap.so.client.orchestration.AAIConfigurationResources;
56 import org.onap.so.client.orchestration.AAINetworkResources;
57 import org.onap.so.client.orchestration.AAIServiceInstanceResources;
58 import org.onap.so.client.orchestration.AAIVfModuleResources;
59 import org.onap.so.client.orchestration.AAIVnfResources;
60 import org.onap.so.client.orchestration.AAIVolumeGroupResources;
61 import org.onap.so.client.orchestration.AAIVpnBindingResources;
62 import org.onap.so.logger.MessageEnum;
63 import org.onap.so.logger.MsoLogger;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.core.env.Environment;
68 import org.springframework.stereotype.Component;
71 public class AAICreateTasks {
73 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, AAICreateTasks.class);
74 private static final Logger logger = LoggerFactory.getLogger(AAICreateTasks.class.getName());
76 private static final String networkTypeProvider = "PROVIDER";
77 private static String NETWORK_COLLECTION_NAME = "networkCollectionName";
78 private static String CONTRAIL_NETWORK_POLICY_FQDN_LIST = "contrailNetworkPolicyFqdnList";
79 private static String HEAT_STACK_ID = "heatStackId";
80 private static String NETWORK_POLICY_FQDN_PARAM = "network-policy-fqdn";
82 private AAIServiceInstanceResources aaiSIResources;
84 private AAIVnfResources aaiVnfResources;
86 private ExceptionBuilder exceptionUtil;
88 private ExtractPojosForBB extractPojosForBB;
90 private AAIVolumeGroupResources aaiVolumeGroupResources;
92 private AAIVfModuleResources aaiVfModuleResources;
94 private AAINetworkResources aaiNetworkResources;
96 private AAIVpnBindingResources aaiVpnBindingResources;
98 private AAIConfigurationResources aaiConfigurationResources;
100 private Environment env;
102 public void createServiceInstance(BuildingBlockExecution execution) {
104 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
105 Customer customer = execution.getGeneralBuildingBlock().getCustomer();
106 aaiSIResources.createServiceInstance(serviceInstance, customer);
107 } catch (Exception ex) {
108 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
112 public void createServiceSubscription(BuildingBlockExecution execution){
114 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution,
115 ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
116 Customer customer = execution.getGeneralBuildingBlock().getCustomer();
117 if (null == customer) {
118 String errorMessage = "Exception in creating ServiceSubscription. Customer not present for ServiceInstanceID: "
119 + serviceInstance.getServiceInstanceId();
120 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, errorMessage, "BPMN", MsoLogger.getServiceName(),
121 MsoLogger.ErrorCode.UnknownError, errorMessage);
122 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, errorMessage);
124 aaiSIResources.createServiceSubscription(customer);
125 } catch (BpmnError ex) {
128 catch (Exception ex) {
129 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
133 public void createProject(BuildingBlockExecution execution) {
135 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
136 Project project = serviceInstance.getProject();
137 if(project != null) {
138 if (project.getProjectName() == null || "".equals(project.getProjectName())) {
139 msoLogger.info("ProjectName is null in input. Skipping create project...");
141 aaiSIResources.createProjectandConnectServiceInstance(project, serviceInstance);
144 } catch (Exception ex) {
145 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
149 public void createOwningEntity(BuildingBlockExecution execution) {
151 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
152 OwningEntity owningEntity = serviceInstance.getOwningEntity();
153 String owningEntityId = owningEntity.getOwningEntityId();
154 String owningEntityName = owningEntity.getOwningEntityName();
155 if (owningEntityId == null || "".equals(owningEntityId)) {
156 String msg = "Exception in AAICreateOwningEntity. OwningEntityId is null.";
157 execution.setVariable("ErrorCreateOEAAI", msg);
158 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
160 if (aaiSIResources.existsOwningEntity(owningEntity)) {
161 aaiSIResources.connectOwningEntityandServiceInstance(owningEntity, serviceInstance);
163 if (owningEntityName == null || "".equals(owningEntityName)) {
164 String msg = "Exception in AAICreateOwningEntity. Can't create an owningEntity with no owningEntityName.";
165 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(),
166 MsoLogger.ErrorCode.UnknownError, msg);
167 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
169 if(aaiSIResources.existsOwningEntityName(owningEntityName)){
170 String msg = "Exception in AAICreateOwningEntity. Can't create OwningEntity as name already exists in AAI associated with a different owning-entity-id (name must be unique)";
171 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(),
172 MsoLogger.ErrorCode.UnknownError, msg);
173 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
175 aaiSIResources.createOwningEntityandConnectServiceInstance(owningEntity, serviceInstance);
180 } catch (Exception ex) {
181 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
185 public void createVnf(BuildingBlockExecution execution) {
187 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
188 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
189 execution.setVariable("callHoming", Boolean.TRUE.equals(vnf.isCallHoming()));
190 aaiVnfResources.createVnfandConnectServiceInstance(vnf, serviceInstance);
191 } catch (Exception ex) {
192 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
196 public void createPlatform(BuildingBlockExecution execution) {
198 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
199 Platform platform = vnf.getPlatform();
200 if(platform != null) {
201 if (platform.getPlatformName() == null || "".equals(platform.getPlatformName())) {
202 msoLogger.debug("PlatformName is null in input. Skipping create platform...");
204 aaiVnfResources.createPlatformandConnectVnf(platform,vnf);
207 } catch (Exception ex) {
208 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
213 public void createLineOfBusiness(BuildingBlockExecution execution) {
215 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
216 LineOfBusiness lineOfBusiness = vnf.getLineOfBusiness();
217 if(lineOfBusiness != null) {
218 if (lineOfBusiness.getLineOfBusinessName() == null || "".equals(lineOfBusiness.getLineOfBusinessName())) {
219 msoLogger.info("lineOfBusiness is null in input. Skipping create lineOfBusiness...");
221 aaiVnfResources.createLineOfBusinessandConnectVnf(lineOfBusiness,vnf);
224 } catch (Exception ex) {
225 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
229 public void createVolumeGroup(BuildingBlockExecution execution) {
231 GeneralBuildingBlock gBBInput = execution.getGeneralBuildingBlock();
233 GenericVnf genericVnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
234 VolumeGroup volumeGroup = extractPojosForBB.extractByKey(execution, ResourceKey.VOLUME_GROUP_ID, execution.getLookupMap().get(ResourceKey.VOLUME_GROUP_ID));
235 CloudRegion cloudRegion = gBBInput.getCloudRegion();
236 aaiVolumeGroupResources.createVolumeGroup(volumeGroup, cloudRegion);
237 aaiVolumeGroupResources.connectVolumeGroupToVnf(genericVnf, volumeGroup, cloudRegion);
238 aaiVolumeGroupResources.connectVolumeGroupToTenant(volumeGroup,cloudRegion);
239 } catch (Exception ex) {
240 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
244 public void createVfModule(BuildingBlockExecution execution) {
246 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
247 VfModule vfModule = extractPojosForBB.extractByKey(execution, ResourceKey.VF_MODULE_ID, execution.getLookupMap().get(ResourceKey.VF_MODULE_ID));
249 if (vfModule.getModelInfoVfModule() != null && !Boolean.TRUE.equals(vfModule.getModelInfoVfModule().getIsBaseBoolean())) {
250 moduleIndex = this.getLowestUnusedVfModuleIndexFromAAIVnfResponse(vnf, vfModule);
252 vfModule.setModuleIndex(moduleIndex);
253 aaiVfModuleResources.createVfModule(vfModule, vnf);
254 } catch (Exception ex) {
255 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
260 * BPMN access method to establish relationships in AAI
264 public void connectVfModuleToVolumeGroup(BuildingBlockExecution execution) {
266 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
267 VfModule vfModule = extractPojosForBB.extractByKey(execution, ResourceKey.VF_MODULE_ID, execution.getLookupMap().get(ResourceKey.VF_MODULE_ID));
268 VolumeGroup volumeGroup = null;
270 volumeGroup = extractPojosForBB.extractByKey(execution, ResourceKey.VOLUME_GROUP_ID, execution.getLookupMap().get(ResourceKey.VOLUME_GROUP_ID));
271 } catch (BBObjectNotFoundException e){
272 msoLogger.info("VolumeGroup not found. Skipping Connect between VfModule and VolumeGroup");
274 if (volumeGroup != null) {
275 aaiVfModuleResources.connectVfModuleToVolumeGroup(vnf, vfModule, volumeGroup, execution.getGeneralBuildingBlock().getCloudRegion());
277 } catch (Exception ex) {
278 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
283 * BPMN access method to execute Create L3Network operation (PUT )in AAI
287 public void createNetwork(BuildingBlockExecution execution) {
289 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
290 L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID, execution.getLookupMap().get(ResourceKey.NETWORK_ID));
291 //set default to false. ToBe updated by SDNC
292 l3network.setIsBoundToVpn(false);
293 //define is bound to vpn flag as true if NEUTRON_NETWORK_TYPE is PROVIDER
294 if (l3network.getModelInfoNetwork().getNeutronNetworkType().equalsIgnoreCase(networkTypeProvider))
295 l3network.setIsBoundToVpn(true);
296 //put network shell in AAI
297 aaiNetworkResources.createNetworkConnectToServiceInstance(l3network, serviceInstance);
298 } catch (Exception ex) {
299 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
302 public void createCustomer(BuildingBlockExecution execution) throws Exception {
304 Customer customer = execution.getGeneralBuildingBlock().getCustomer();
306 aaiVpnBindingResources.createCustomer(customer);
307 } catch(Exception ex) {
308 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
313 * BPMN access method to execute NetworkCollection operation (PUT) in AAI
317 public void createNetworkCollection(BuildingBlockExecution execution) {
319 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
320 Collection networkCollection = serviceInstance.getCollection();
321 //pass name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
323 networkCollection.setName(execution.getVariable(NETWORK_COLLECTION_NAME));
324 aaiNetworkResources.createNetworkCollection(networkCollection);
325 } catch (Exception ex) {
326 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
331 * BPMN access method to execute NetworkCollectionInstanceGroup operation (PUT) in AAI
335 public void createNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
337 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
338 InstanceGroup instanceGroup = serviceInstance.getCollection().getInstanceGroup();
339 //set name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
340 instanceGroup.setInstanceGroupName(execution.getVariable(NETWORK_COLLECTION_NAME));
342 aaiNetworkResources.createNetworkInstanceGroup(instanceGroup);
343 } catch (Exception ex) {
344 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
350 * BPMN access method to establish relationships in AAI
354 public void connectNetworkToTenant(BuildingBlockExecution execution) {
356 L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID, execution.getLookupMap().get(ResourceKey.NETWORK_ID));
357 aaiNetworkResources.connectNetworkToTenant(l3network, execution.getGeneralBuildingBlock().getCloudRegion());
358 } catch (Exception ex) {
359 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
364 * BPMN access method to establish relationships in AAI
368 public void connectNetworkToCloudRegion(BuildingBlockExecution execution) {
370 L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID, execution.getLookupMap().get(ResourceKey.NETWORK_ID));
371 aaiNetworkResources.connectNetworkToCloudRegion(l3network, execution.getGeneralBuildingBlock().getCloudRegion());
372 } catch (Exception ex) {
373 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
378 * BPMN access method to establish relationships in AAI
382 public void connectVnfToCloudRegion(BuildingBlockExecution execution) {
384 boolean cloudRegionsToSkip = false;
385 String[] cloudRegions = env.getProperty("mso.bpmn.cloudRegionIdsToSkipAddingVnfEdgesTo", String[].class);
386 if (cloudRegions != null){
387 cloudRegionsToSkip = Arrays.stream(cloudRegions).anyMatch(execution.getGeneralBuildingBlock().getCloudRegion().getLcpCloudRegionId()::equals);
389 if(!cloudRegionsToSkip) {
390 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
391 aaiVnfResources.connectVnfToCloudRegion(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
393 } catch (Exception ex) {
394 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
399 * BPMN access method to establish relationships in AAI
403 public void connectVnfToTenant(BuildingBlockExecution execution) {
405 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID, execution.getLookupMap().get(ResourceKey.GENERIC_VNF_ID));
406 aaiVnfResources.connectVnfToTenant(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
407 } catch (Exception ex) {
408 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
413 * BPMN access method to establish relationships in AAI
417 public void connectNetworkToNetworkCollectionServiceInstance(BuildingBlockExecution execution) {
419 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
420 L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID, execution.getLookupMap().get(ResourceKey.NETWORK_ID));
421 aaiNetworkResources.connectNetworkToNetworkCollectionServiceInstance(l3network, serviceInstance);
422 } catch (Exception ex) {
423 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
428 * BPMN access method to establish relationships in AAI
432 public void connectNetworkToNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
434 ServiceInstance serviceInstance = extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID, execution.getLookupMap().get(ResourceKey.SERVICE_INSTANCE_ID));
435 L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID, execution.getLookupMap().get(ResourceKey.NETWORK_ID));
436 //connect network only if Instance Group / Collection objects exist
437 if (serviceInstance.getCollection() != null && serviceInstance.getCollection().getInstanceGroup() != null)
438 aaiNetworkResources.connectNetworkToNetworkCollectionInstanceGroup(l3network, serviceInstance.getCollection().getInstanceGroup());
439 } catch (Exception ex) {
440 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
444 public void createConfiguration(BuildingBlockExecution execution){
446 Configuration configuration = extractPojosForBB.extractByKey(execution, ResourceKey.CONFIGURATION_ID, execution.getLookupMap().get(ResourceKey.CONFIGURATION_ID));
447 aaiConfigurationResources.createConfiguration(configuration);
448 } catch (Exception ex) {
449 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
453 public void createNetworkPolicies(BuildingBlockExecution execution) {
455 String fqdns = execution.getVariable(CONTRAIL_NETWORK_POLICY_FQDN_LIST);
456 if (fqdns != null && !fqdns.isEmpty()) {
457 String fqdnList[] = fqdns.split(",");
458 int fqdnCount = fqdnList.length;
460 for (int i=0; i < fqdnCount; i++) {
461 String fqdn = fqdnList[i];
462 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.NETWORK_POLICY);
463 uri.queryParam(NETWORK_POLICY_FQDN_PARAM, fqdn);
464 Optional<org.onap.aai.domain.yang.NetworkPolicy> oNetPolicy = aaiNetworkResources.getNetworkPolicy(uri);
465 if(!oNetPolicy.isPresent()) {
466 msoLogger.debug("This network policy FQDN is not in AAI yet: " + fqdn);
467 String networkPolicyId = UUID.randomUUID().toString();
468 msoLogger.debug("Adding network-policy with network-policy-id " + networkPolicyId);
469 NetworkPolicy networkPolicy = new NetworkPolicy();
470 networkPolicy.setNetworkPolicyId(networkPolicyId);
471 networkPolicy.setNetworkPolicyFqdn(fqdn);
472 networkPolicy.setHeatStackId(execution.getVariable(HEAT_STACK_ID));
474 aaiNetworkResources.createNetworkPolicy(networkPolicy);
479 } catch (Exception ex) {
480 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
485 * Groups existing vf modules by the model uuid of our new vf module and returns the lowest unused index
487 * if we have a module type A, and there are 3 instances of those,
488 * and then module type B has 2 instances, if we are adding a new module type A,
489 * the vf-module-index should be 3 assuming contiguous indices (not 5, or 2)
492 protected int getLowestUnusedVfModuleIndexFromAAIVnfResponse(GenericVnf genericVnf, VfModule newVfModule) {
494 String newVfModuleModelInvariantUUID = null;
495 if (newVfModule.getModelInfoVfModule() != null) {
496 newVfModuleModelInvariantUUID = newVfModule.getModelInfoVfModule().getModelInvariantUUID();
500 if (genericVnf != null && genericVnf.getVfModules() != null && !genericVnf.getVfModules().isEmpty()) {
501 List<VfModule> modules = genericVnf.getVfModules().stream().filter(item -> !item.getVfModuleId().equals(newVfModule.getVfModuleId())).collect(Collectors.toList());
502 TreeSet<Integer> moduleIndices = new TreeSet<>();
503 int nullIndexFound = 0;
504 for (VfModule vfModule : modules) {
505 if (vfModule.getModelInfoVfModule() != null) {
506 if (vfModule.getModelInfoVfModule().getModelInvariantUUID().equals(newVfModuleModelInvariantUUID)) {
507 if (vfModule.getModuleIndex() != null) {
508 moduleIndices.add(vfModule.getModuleIndex());
511 logger.warn("Found null index for vf-module-id {} and model-invariant-uuid {}", vfModule.getVfModuleId(), vfModule.getModelInfoVfModule().getModelInvariantUUID());
517 return calculateUnusedIndex(moduleIndices, nullIndexFound);
523 protected int calculateUnusedIndex(TreeSet<Integer> moduleIndices, int nullIndexFound) {
524 //pad array with nulls
525 Integer[] temp = new Integer[moduleIndices.size() + nullIndexFound];
526 Integer[] array = moduleIndices.toArray(temp);
528 //when a null is found skip that potential value
529 //effectively creates something like, [0,1,3,null,null] -> [0,1,null(2),3,null(4)]
530 for (int i=0; i < array.length; i++, result++) {
531 if (Integer.valueOf(result) != array[i]) {
532 if (nullIndexFound > 0) {