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