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