Merge "Commented out updatedAttribute declaration to prevent static analyzer warning...
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / aai / tasks / AAICreateTasks.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.aai.tasks;
24
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.TreeSet;
29 import java.util.UUID;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import org.onap.so.logger.LoggingAnchor;
33 import org.camunda.bpm.engine.delegate.BpmnError;
34 import org.onap.so.bpmn.common.BuildingBlockExecution;
35 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
36 import org.onap.so.bpmn.servicedecomposition.bbobjects.Collection;
37 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
38 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
40 import org.onap.so.bpmn.servicedecomposition.bbobjects.InstanceGroup;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.LineOfBusiness;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.OwningEntity;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.Platform;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.Project;
47 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
48 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
49 import org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup;
50 import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
51 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
52 import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
53 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
54 import org.onap.so.client.aai.AAIObjectPlurals;
55 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
56 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
57 import org.onap.so.client.exception.BBObjectNotFoundException;
58 import org.onap.so.client.exception.ExceptionBuilder;
59 import org.onap.so.client.orchestration.AAIConfigurationResources;
60 import org.onap.so.client.orchestration.AAIInstanceGroupResources;
61 import org.onap.so.client.orchestration.AAINetworkResources;
62 import org.onap.so.client.orchestration.AAIServiceInstanceResources;
63 import org.onap.so.client.orchestration.AAIVfModuleResources;
64 import org.onap.so.client.orchestration.AAIVnfResources;
65 import org.onap.so.client.orchestration.AAIVolumeGroupResources;
66 import org.onap.so.client.orchestration.AAIVpnBindingResources;
67 import org.onap.so.logger.ErrorCode;
68 import org.onap.so.logger.MessageEnum;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71 import org.springframework.beans.factory.annotation.Autowired;
72 import org.springframework.core.env.Environment;
73 import org.springframework.stereotype.Component;
74
75 @Component
76 public class AAICreateTasks {
77
78     private static final Logger logger = LoggerFactory.getLogger(AAICreateTasks.class);
79     private static final String networkTypeProvider = "PROVIDER";
80     private static String NETWORK_COLLECTION_NAME = "networkCollectionName";
81     private static String CONTRAIL_NETWORK_POLICY_FQDN_LIST = "contrailNetworkPolicyFqdnList";
82     private static String HEAT_STACK_ID = "heatStackId";
83     private static String NETWORK_POLICY_FQDN_PARAM = "network-policy-fqdn";
84     @Autowired
85     private AAIServiceInstanceResources aaiSIResources;
86     @Autowired
87     private AAIVnfResources aaiVnfResources;
88     @Autowired
89     private ExceptionBuilder exceptionUtil;
90     @Autowired
91     private ExtractPojosForBB extractPojosForBB;
92     @Autowired
93     private AAIVolumeGroupResources aaiVolumeGroupResources;
94     @Autowired
95     private AAIVfModuleResources aaiVfModuleResources;
96     @Autowired
97     private AAINetworkResources aaiNetworkResources;
98     @Autowired
99     private AAIVpnBindingResources aaiVpnBindingResources;
100     @Autowired
101     private AAIConfigurationResources aaiConfigurationResources;
102     @Autowired
103     private AAIInstanceGroupResources aaiInstanceGroupResources;
104     @Autowired
105     private Environment env;
106
107     public void createServiceInstance(BuildingBlockExecution execution) {
108         try {
109             ServiceInstance serviceInstance =
110                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
111             Customer customer = execution.getGeneralBuildingBlock().getCustomer();
112             aaiSIResources.createServiceInstance(serviceInstance, customer);
113         } catch (Exception ex) {
114             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
115         }
116     }
117
118     public void createServiceSubscription(BuildingBlockExecution execution) {
119         try {
120             ServiceInstance serviceInstance =
121                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
122             Customer customer = execution.getGeneralBuildingBlock().getCustomer();
123             if (null == customer) {
124                 String errorMessage =
125                         "Exception in creating ServiceSubscription. Customer not present for ServiceInstanceID: "
126                                 + serviceInstance.getServiceInstanceId();
127                 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), errorMessage,
128                         "BPMN", ErrorCode.UnknownError.getValue(), errorMessage);
129                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, errorMessage);
130             }
131             aaiSIResources.createServiceSubscription(customer);
132         } catch (BpmnError ex) {
133             throw ex;
134         } catch (Exception ex) {
135             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
136         }
137     }
138
139     public void createProject(BuildingBlockExecution execution) {
140         try {
141             ServiceInstance serviceInstance =
142                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
143             Project project = serviceInstance.getProject();
144             if (project != null) {
145                 if (project.getProjectName() == null || "".equals(project.getProjectName())) {
146                     logger.info("ProjectName is null in input. Skipping create project...");
147                 } else {
148                     aaiSIResources.createProjectandConnectServiceInstance(project, serviceInstance);
149                 }
150             }
151         } catch (Exception ex) {
152             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
153         }
154     }
155
156     public void createOwningEntity(BuildingBlockExecution execution) {
157         try {
158             ServiceInstance serviceInstance =
159                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
160             OwningEntity owningEntity = serviceInstance.getOwningEntity();
161             String owningEntityId = owningEntity.getOwningEntityId();
162             String owningEntityName = owningEntity.getOwningEntityName();
163             if (owningEntityId == null || "".equals(owningEntityId)) {
164                 String msg = "Exception in AAICreateOwningEntity. OwningEntityId is null.";
165                 execution.setVariable("ErrorCreateOEAAI", msg);
166                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
167             } else {
168                 if (aaiSIResources.existsOwningEntity(owningEntity)) {
169                     aaiSIResources.connectOwningEntityandServiceInstance(owningEntity, serviceInstance);
170                 } else {
171                     if (owningEntityName == null || "".equals(owningEntityName)) {
172                         String msg =
173                                 "Exception in AAICreateOwningEntity. Can't create an owningEntity with no owningEntityName.";
174                         logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
175                                 ErrorCode.UnknownError.getValue(), msg);
176                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
177                     } else {
178                         if (aaiSIResources.existsOwningEntityName(owningEntityName)) {
179                             String msg =
180                                     "Exception in AAICreateOwningEntity. Can't create OwningEntity as name already exists in AAI associated with a different owning-entity-id (name must be unique)";
181                             logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg,
182                                     "BPMN", ErrorCode.UnknownError.getValue(), msg);
183                             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
184                         } else {
185                             aaiSIResources.createOwningEntityandConnectServiceInstance(owningEntity, serviceInstance);
186                         }
187                     }
188                 }
189             }
190         } catch (Exception ex) {
191             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
192         }
193     }
194
195     public void createVnf(BuildingBlockExecution execution) {
196         try {
197             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
198             ServiceInstance serviceInstance =
199                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
200             execution.setVariable("homing", Boolean.TRUE.equals(vnf.isCallHoming()));
201             aaiVnfResources.createVnfandConnectServiceInstance(vnf, serviceInstance);
202         } catch (Exception ex) {
203             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
204         }
205     }
206
207     public void createPlatform(BuildingBlockExecution execution) {
208         try {
209             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
210             Platform platform = vnf.getPlatform();
211             if (platform != null) {
212                 if (platform.getPlatformName() == null || "".equals(platform.getPlatformName())) {
213                     logger.debug("PlatformName is null in input. Skipping create platform...");
214                 } else {
215                     List<String> platforms = splitCDL(platform.getPlatformName());
216                     platforms.stream().forEach(platformName -> aaiVnfResources
217                             .createPlatformandConnectVnf(new Platform(platformName), vnf));
218                 }
219             }
220         } catch (Exception ex) {
221             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
222         }
223
224     }
225
226     public List<String> splitCDL(String str) {
227         return Stream.of(str.split(",")).map(String::trim).map(elem -> new String(elem)).collect(Collectors.toList());
228     }
229
230     public void createLineOfBusiness(BuildingBlockExecution execution) {
231         try {
232             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
233             LineOfBusiness lineOfBusiness = vnf.getLineOfBusiness();
234             if (lineOfBusiness != null) {
235                 if (lineOfBusiness.getLineOfBusinessName() == null
236                         || "".equals(lineOfBusiness.getLineOfBusinessName())) {
237                     logger.info("lineOfBusiness is null in input. Skipping create lineOfBusiness...");
238                 } else {
239                     List<String> lineOfBussinesses = splitCDL(lineOfBusiness.getLineOfBusinessName());
240                     lineOfBussinesses.stream().forEach(lobName -> aaiVnfResources
241                             .createLineOfBusinessandConnectVnf(new LineOfBusiness(lobName), vnf));
242                 }
243             }
244         } catch (Exception ex) {
245             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
246         }
247     }
248
249     public void createVolumeGroup(BuildingBlockExecution execution) {
250         try {
251             GeneralBuildingBlock gBBInput = execution.getGeneralBuildingBlock();
252
253             GenericVnf genericVnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
254             VolumeGroup volumeGroup = extractPojosForBB.extractByKey(execution, ResourceKey.VOLUME_GROUP_ID);
255             CloudRegion cloudRegion = gBBInput.getCloudRegion();
256             aaiVolumeGroupResources.createVolumeGroup(volumeGroup, cloudRegion);
257             aaiVolumeGroupResources.connectVolumeGroupToVnf(genericVnf, volumeGroup, cloudRegion);
258             aaiVolumeGroupResources.connectVolumeGroupToTenant(volumeGroup, cloudRegion);
259         } catch (Exception ex) {
260             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
261         }
262     }
263
264     public void createVfModule(BuildingBlockExecution execution) {
265         try {
266             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
267             VfModule vfModule = extractPojosForBB.extractByKey(execution, ResourceKey.VF_MODULE_ID);
268             int moduleIndex = 0;
269             if (vfModule.getModelInfoVfModule() != null
270                     && !Boolean.TRUE.equals(vfModule.getModelInfoVfModule().getIsBaseBoolean())) {
271                 moduleIndex = this.getLowestUnusedVfModuleIndexFromAAIVnfResponse(vnf, vfModule);
272             }
273             vfModule.setModuleIndex(moduleIndex);
274             aaiVfModuleResources.createVfModule(vfModule, vnf);
275         } catch (Exception ex) {
276             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
277         }
278     }
279
280     /**
281      * BPMN access method to establish relationships in AAI
282      * 
283      * @param execution
284      * @throws Exception
285      */
286     public void connectVfModuleToVolumeGroup(BuildingBlockExecution execution) {
287         try {
288             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
289             VfModule vfModule = extractPojosForBB.extractByKey(execution, ResourceKey.VF_MODULE_ID);
290             VolumeGroup volumeGroup = null;
291             try {
292                 volumeGroup = extractPojosForBB.extractByKey(execution, ResourceKey.VOLUME_GROUP_ID);
293             } catch (BBObjectNotFoundException e) {
294                 logger.info("VolumeGroup not found. Skipping Connect between VfModule and VolumeGroup");
295             }
296             if (volumeGroup != null) {
297                 aaiVfModuleResources.connectVfModuleToVolumeGroup(vnf, vfModule, volumeGroup,
298                         execution.getGeneralBuildingBlock().getCloudRegion());
299             }
300         } catch (Exception ex) {
301             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
302         }
303     }
304
305     /**
306      * BPMN access method to execute Create L3Network operation (PUT )in AAI
307      * 
308      * @param execution
309      * @throws Exception
310      */
311     public void createNetwork(BuildingBlockExecution execution) {
312         try {
313             ServiceInstance serviceInstance =
314                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
315             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
316             // set default to false. ToBe updated by SDNC
317             l3network.setIsBoundToVpn(false);
318             // define is bound to vpn flag as true if NEUTRON_NETWORK_TYPE is PROVIDER
319             if (l3network.getModelInfoNetwork().getNeutronNetworkType().equalsIgnoreCase(networkTypeProvider))
320                 l3network.setIsBoundToVpn(true);
321             // put network shell in AAI
322             aaiNetworkResources.createNetworkConnectToServiceInstance(l3network, serviceInstance);
323         } catch (Exception ex) {
324             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
325         }
326     }
327
328     public void createCustomer(BuildingBlockExecution execution) throws Exception {
329         try {
330             Customer customer = execution.getGeneralBuildingBlock().getCustomer();
331
332             aaiVpnBindingResources.createCustomer(customer);
333         } catch (Exception ex) {
334             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
335         }
336     }
337
338     /**
339      * BPMN access method to execute NetworkCollection operation (PUT) in AAI
340      * 
341      * @param execution
342      * @throws Exception
343      */
344     public void createNetworkCollection(BuildingBlockExecution execution) {
345         try {
346             ServiceInstance serviceInstance =
347                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
348             Collection networkCollection = serviceInstance.getCollection();
349             // pass name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
350             // put shell in AAI
351             networkCollection.setName(execution.getVariable(NETWORK_COLLECTION_NAME));
352             aaiNetworkResources.createNetworkCollection(networkCollection);
353         } catch (Exception ex) {
354             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
355         }
356     }
357
358     /**
359      * BPMN access method to execute NetworkCollectionInstanceGroup operation (PUT) in AAI
360      * 
361      * @param execution
362      * @throws Exception
363      */
364     public void createNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
365         try {
366             ServiceInstance serviceInstance =
367                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
368             InstanceGroup instanceGroup = serviceInstance.getCollection().getInstanceGroup();
369             // set name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
370             instanceGroup.setInstanceGroupName(execution.getVariable(NETWORK_COLLECTION_NAME));
371             // put shell in AAI
372             aaiNetworkResources.createNetworkInstanceGroup(instanceGroup);
373         } catch (Exception ex) {
374             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
375         }
376     }
377
378
379     /**
380      * BPMN access method to establish relationships in AAI
381      * 
382      * @param execution
383      * @throws Exception
384      */
385     public void connectNetworkToTenant(BuildingBlockExecution execution) {
386         try {
387             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
388             aaiNetworkResources.connectNetworkToTenant(l3network, execution.getGeneralBuildingBlock().getCloudRegion());
389         } catch (Exception ex) {
390             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
391         }
392     }
393
394     /**
395      * BPMN access method to establish relationships in AAI
396      * 
397      * @param execution
398      * @throws Exception
399      */
400     public void connectNetworkToCloudRegion(BuildingBlockExecution execution) {
401         try {
402             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
403             aaiNetworkResources.connectNetworkToCloudRegion(l3network,
404                     execution.getGeneralBuildingBlock().getCloudRegion());
405         } catch (Exception ex) {
406             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
407         }
408     }
409
410     /**
411      * BPMN access method to establish relationships in AAI
412      * 
413      * @param execution
414      * @throws Exception
415      */
416     public void connectVnfToCloudRegion(BuildingBlockExecution execution) {
417         try {
418             boolean cloudRegionsToSkip = false;
419             String[] cloudRegions = env.getProperty("mso.bpmn.cloudRegionIdsToSkipAddingVnfEdgesTo", String[].class);
420             if (cloudRegions != null) {
421                 cloudRegionsToSkip = Arrays.stream(cloudRegions)
422                         .anyMatch(execution.getGeneralBuildingBlock().getCloudRegion().getLcpCloudRegionId()::equals);
423             }
424             if (!cloudRegionsToSkip) {
425                 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
426                 aaiVnfResources.connectVnfToCloudRegion(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
427             }
428         } catch (Exception ex) {
429             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
430         }
431     }
432
433     /**
434      * BPMN access method to establish relationships in AAI
435      * 
436      * @param execution
437      * @throws Exception
438      */
439     public void connectVnfToTenant(BuildingBlockExecution execution) {
440         try {
441             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
442             aaiVnfResources.connectVnfToTenant(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
443         } catch (Exception ex) {
444             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
445         }
446     }
447
448     /**
449      * BPMN access method to establish relationships in AAI
450      * 
451      * @param execution
452      * @throws Exception
453      */
454     public void connectNetworkToNetworkCollectionServiceInstance(BuildingBlockExecution execution) {
455         try {
456             ServiceInstance serviceInstance =
457                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
458             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
459             aaiNetworkResources.connectNetworkToNetworkCollectionServiceInstance(l3network, serviceInstance);
460         } catch (Exception ex) {
461             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
462         }
463     }
464
465     /**
466      * BPMN access method to establish relationships in AAI
467      * 
468      * @param execution
469      * @throws Exception
470      */
471     public void connectNetworkToNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
472         try {
473             ServiceInstance serviceInstance =
474                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
475             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
476             // connect network only if Instance Group / Collection objects exist
477             if (serviceInstance.getCollection() != null && serviceInstance.getCollection().getInstanceGroup() != null)
478                 aaiNetworkResources.connectNetworkToNetworkCollectionInstanceGroup(l3network,
479                         serviceInstance.getCollection().getInstanceGroup());
480         } catch (Exception ex) {
481             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
482         }
483     }
484
485     public void createConfiguration(BuildingBlockExecution execution) {
486         try {
487             Configuration configuration = extractPojosForBB.extractByKey(execution, ResourceKey.CONFIGURATION_ID);
488             aaiConfigurationResources.createConfiguration(configuration);
489         } catch (Exception ex) {
490             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
491         }
492     }
493
494     public void createInstanceGroupVnf(BuildingBlockExecution execution) {
495         try {
496             ServiceInstance serviceInstance =
497                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
498             InstanceGroup instanceGroup = extractPojosForBB.extractByKey(execution, ResourceKey.INSTANCE_GROUP_ID);
499             aaiInstanceGroupResources.createInstanceGroupandConnectServiceInstance(instanceGroup, serviceInstance);
500         } catch (Exception ex) {
501             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
502         }
503     }
504
505     public void createNetworkPolicies(BuildingBlockExecution execution) {
506         try {
507             String fqdns = execution.getVariable(CONTRAIL_NETWORK_POLICY_FQDN_LIST);
508             if (fqdns != null && !fqdns.isEmpty()) {
509                 String fqdnList[] = fqdns.split(",");
510                 int fqdnCount = fqdnList.length;
511                 if (fqdnCount > 0) {
512                     for (int i = 0; i < fqdnCount; i++) {
513                         String fqdn = fqdnList[i];
514                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.NETWORK_POLICY);
515                         uri.queryParam(NETWORK_POLICY_FQDN_PARAM, fqdn);
516                         Optional<org.onap.aai.domain.yang.NetworkPolicy> oNetPolicy =
517                                 aaiNetworkResources.getNetworkPolicy(uri);
518                         if (!oNetPolicy.isPresent()) {
519                             logger.debug("This network policy FQDN is not in AAI yet: {}", fqdn);
520                             String networkPolicyId = UUID.randomUUID().toString();
521                             logger.debug("Adding network-policy with network-policy-id {}", networkPolicyId);
522                             NetworkPolicy networkPolicy = new NetworkPolicy();
523                             networkPolicy.setNetworkPolicyId(networkPolicyId);
524                             networkPolicy.setNetworkPolicyFqdn(fqdn);
525                             networkPolicy.setHeatStackId(execution.getVariable(HEAT_STACK_ID));
526
527                             aaiNetworkResources.createNetworkPolicy(networkPolicy);
528                         }
529                     }
530                 }
531             }
532         } catch (Exception ex) {
533             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
534         }
535     }
536
537     /**
538      * Groups existing vf modules by the model uuid of our new vf module and returns the lowest unused index
539      * 
540      * if we have a module type A, and there are 3 instances of those, and then module type B has 2 instances, if we are
541      * adding a new module type A, the vf-module-index should be 3 assuming contiguous indices (not 5, or 2)
542      * 
543      */
544     protected int getLowestUnusedVfModuleIndexFromAAIVnfResponse(GenericVnf genericVnf, VfModule newVfModule) {
545
546         String newVfModuleModelInvariantUUID = null;
547         if (newVfModule.getModelInfoVfModule() != null) {
548             newVfModuleModelInvariantUUID = newVfModule.getModelInfoVfModule().getModelInvariantUUID();
549         }
550
551
552         if (genericVnf != null && genericVnf.getVfModules() != null && !genericVnf.getVfModules().isEmpty()) {
553             List<VfModule> modules = genericVnf.getVfModules().stream()
554                     .filter(item -> !item.getVfModuleId().equals(newVfModule.getVfModuleId()))
555                     .collect(Collectors.toList());
556             TreeSet<Integer> moduleIndices = new TreeSet<>();
557             int nullIndexFound = 0;
558             for (VfModule vfModule : modules) {
559                 if (vfModule.getModelInfoVfModule() != null) {
560                     if (vfModule.getModelInfoVfModule().getModelInvariantUUID().equals(newVfModuleModelInvariantUUID)) {
561                         if (vfModule.getModuleIndex() != null) {
562                             moduleIndices.add(vfModule.getModuleIndex());
563                         } else {
564                             nullIndexFound++;
565                             logger.warn("Found null index for vf-module-id {} and model-invariant-uuid {}",
566                                     vfModule.getVfModuleId(), vfModule.getModelInfoVfModule().getModelInvariantUUID());
567                         }
568                     }
569                 }
570             }
571
572             return calculateUnusedIndex(moduleIndices, nullIndexFound);
573         } else {
574             return 0;
575         }
576     }
577
578     protected int calculateUnusedIndex(TreeSet<Integer> moduleIndices, int nullIndexFound) {
579         // pad array with nulls
580         Integer[] temp = new Integer[moduleIndices.size() + nullIndexFound];
581         Integer[] array = moduleIndices.toArray(temp);
582         int result = 0;
583         // when a null is found skip that potential value
584         // effectively creates something like, [0,1,3,null,null] -> [0,1,null(2),3,null(4)]
585         for (int i = 0; i < array.length; i++, result++) {
586             if (Integer.valueOf(result) != array[i]) {
587                 if (nullIndexFound > 0) {
588                     nullIndexFound--;
589                     i--;
590                 } else {
591                     break;
592                 }
593             }
594         }
595
596         return result;
597     }
598 }