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