Validate names before writing to A&AI
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / aai / tasks / AAICreateTasks.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.aai.tasks;
24
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.TreeSet;
29 import java.util.UUID;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import org.onap.so.logger.LoggingAnchor;
33 import org.camunda.bpm.engine.delegate.BpmnError;
34 import org.onap.so.bpmn.common.BuildingBlockExecution;
35 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
36 import org.onap.so.bpmn.servicedecomposition.bbobjects.Collection;
37 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
38 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
40 import org.onap.so.bpmn.servicedecomposition.bbobjects.InstanceGroup;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.LineOfBusiness;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.OwningEntity;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.Platform;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.Project;
47 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
48 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
49 import org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup;
50 import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
51 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
52 import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
53 import org.onap.so.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(LoggingAnchor.FIVE, 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(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
174                                 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(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg,
181                                     "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("homing", 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             Boolean alaCarte = execution.getVariable(A_LA_CARTE);
313             ServiceInstance serviceInstance =
314                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
315             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
316             if (alaCarte != null && alaCarte && aaiNetworkResources.checkNetworkNameInUse(l3network.getNetworkName())) {
317                 throw new DuplicateNameException("l3Network", l3network.getNetworkName());
318             }
319             // set default to false. ToBe updated by SDNC
320             l3network.setIsBoundToVpn(false);
321             // define is bound to vpn flag as true if NEUTRON_NETWORK_TYPE is PROVIDER
322             if (l3network.getModelInfoNetwork().getNeutronNetworkType().equalsIgnoreCase(networkTypeProvider))
323                 l3network.setIsBoundToVpn(true);
324             // put network shell in AAI
325             aaiNetworkResources.createNetworkConnectToServiceInstance(l3network, serviceInstance);
326         } catch (Exception ex) {
327             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
328         }
329     }
330
331     public void createCustomer(BuildingBlockExecution execution) throws Exception {
332         try {
333             Customer customer = execution.getGeneralBuildingBlock().getCustomer();
334
335             aaiVpnBindingResources.createCustomer(customer);
336         } catch (Exception ex) {
337             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
338         }
339     }
340
341     /**
342      * BPMN access method to execute NetworkCollection operation (PUT) in AAI
343      * 
344      * @param execution
345      * @throws Exception
346      */
347     public void createNetworkCollection(BuildingBlockExecution execution) {
348         try {
349             ServiceInstance serviceInstance =
350                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
351             Collection networkCollection = serviceInstance.getCollection();
352             // pass name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
353             // put shell in AAI
354             networkCollection.setName(execution.getVariable(NETWORK_COLLECTION_NAME));
355             aaiNetworkResources.createNetworkCollection(networkCollection);
356         } catch (Exception ex) {
357             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
358         }
359     }
360
361     /**
362      * BPMN access method to execute NetworkCollectionInstanceGroup operation (PUT) in AAI
363      * 
364      * @param execution
365      * @throws Exception
366      */
367     public void createNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
368         try {
369             Boolean alaCarte = execution.getVariable(A_LA_CARTE);
370             ServiceInstance serviceInstance =
371                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
372             InstanceGroup instanceGroup = serviceInstance.getCollection().getInstanceGroup();
373             // set name generated for NetworkCollection/NetworkCollectionInstanceGroup in previous step of the BB flow
374             instanceGroup.setInstanceGroupName(execution.getVariable(NETWORK_COLLECTION_NAME));
375             if (alaCarte != null && alaCarte
376                     && aaiInstanceGroupResources.checkInstanceGroupNameInUse(instanceGroup.getInstanceGroupName())) {
377                 throw new DuplicateNameException("instance-group", instanceGroup.getInstanceGroupName());
378             }
379             // put shell in AAI
380             aaiNetworkResources.createNetworkInstanceGroup(instanceGroup);
381         } catch (Exception ex) {
382             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
383         }
384     }
385
386
387     /**
388      * BPMN access method to establish relationships in AAI
389      * 
390      * @param execution
391      * @throws Exception
392      */
393     public void connectNetworkToTenant(BuildingBlockExecution execution) {
394         try {
395             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
396             aaiNetworkResources.connectNetworkToTenant(l3network, execution.getGeneralBuildingBlock().getCloudRegion());
397         } catch (Exception ex) {
398             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
399         }
400     }
401
402     /**
403      * BPMN access method to establish relationships in AAI
404      * 
405      * @param execution
406      * @throws Exception
407      */
408     public void connectNetworkToCloudRegion(BuildingBlockExecution execution) {
409         try {
410             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
411             aaiNetworkResources.connectNetworkToCloudRegion(l3network,
412                     execution.getGeneralBuildingBlock().getCloudRegion());
413         } catch (Exception ex) {
414             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
415         }
416     }
417
418     /**
419      * BPMN access method to establish relationships in AAI
420      * 
421      * @param execution
422      * @throws Exception
423      */
424     public void connectVnfToCloudRegion(BuildingBlockExecution execution) {
425         try {
426             boolean cloudRegionsToSkip = false;
427             String[] cloudRegions = env.getProperty("mso.bpmn.cloudRegionIdsToSkipAddingVnfEdgesTo", String[].class);
428             if (cloudRegions != null) {
429                 cloudRegionsToSkip = Arrays.stream(cloudRegions)
430                         .anyMatch(execution.getGeneralBuildingBlock().getCloudRegion().getLcpCloudRegionId()::equals);
431             }
432             if (!cloudRegionsToSkip) {
433                 GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
434                 aaiVnfResources.connectVnfToCloudRegion(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
435             }
436         } catch (Exception ex) {
437             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
438         }
439     }
440
441     /**
442      * BPMN access method to establish relationships in AAI
443      * 
444      * @param execution
445      * @throws Exception
446      */
447     public void connectVnfToTenant(BuildingBlockExecution execution) {
448         try {
449             GenericVnf vnf = extractPojosForBB.extractByKey(execution, ResourceKey.GENERIC_VNF_ID);
450             aaiVnfResources.connectVnfToTenant(vnf, execution.getGeneralBuildingBlock().getCloudRegion());
451         } catch (Exception ex) {
452             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
453         }
454     }
455
456     /**
457      * BPMN access method to establish relationships in AAI
458      * 
459      * @param execution
460      * @throws Exception
461      */
462     public void connectNetworkToNetworkCollectionServiceInstance(BuildingBlockExecution execution) {
463         try {
464             ServiceInstance serviceInstance =
465                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
466             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
467             aaiNetworkResources.connectNetworkToNetworkCollectionServiceInstance(l3network, serviceInstance);
468         } catch (Exception ex) {
469             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
470         }
471     }
472
473     /**
474      * BPMN access method to establish relationships in AAI
475      * 
476      * @param execution
477      * @throws Exception
478      */
479     public void connectNetworkToNetworkCollectionInstanceGroup(BuildingBlockExecution execution) {
480         try {
481             ServiceInstance serviceInstance =
482                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
483             L3Network l3network = extractPojosForBB.extractByKey(execution, ResourceKey.NETWORK_ID);
484             // connect network only if Instance Group / Collection objects exist
485             if (serviceInstance.getCollection() != null && serviceInstance.getCollection().getInstanceGroup() != null)
486                 aaiNetworkResources.connectNetworkToNetworkCollectionInstanceGroup(l3network,
487                         serviceInstance.getCollection().getInstanceGroup());
488         } catch (Exception ex) {
489             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
490         }
491     }
492
493     public void createConfiguration(BuildingBlockExecution execution) {
494         try {
495             Boolean alaCarte = execution.getVariable(A_LA_CARTE);
496             Configuration configuration = extractPojosForBB.extractByKey(execution, ResourceKey.CONFIGURATION_ID);
497             if (alaCarte != null && alaCarte
498                     && aaiConfigurationResources.checkConfigurationNameInUse(configuration.getConfigurationName())) {
499                 throw new DuplicateNameException("configuration", configuration.getConfigurationName());
500             }
501             aaiConfigurationResources.createConfiguration(configuration);
502         } catch (Exception ex) {
503             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
504         }
505     }
506
507     public void createInstanceGroupVnf(BuildingBlockExecution execution) {
508         try {
509             Boolean alaCarte = execution.getVariable(A_LA_CARTE);
510             ServiceInstance serviceInstance =
511                     extractPojosForBB.extractByKey(execution, ResourceKey.SERVICE_INSTANCE_ID);
512             InstanceGroup instanceGroup = extractPojosForBB.extractByKey(execution, ResourceKey.INSTANCE_GROUP_ID);
513             if (alaCarte != null && alaCarte
514                     && aaiInstanceGroupResources.checkInstanceGroupNameInUse(instanceGroup.getInstanceGroupName())) {
515                 throw new DuplicateNameException("instance-group", instanceGroup.getInstanceGroupName());
516             }
517             aaiInstanceGroupResources.createInstanceGroupandConnectServiceInstance(instanceGroup, serviceInstance);
518         } catch (Exception ex) {
519             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
520         }
521     }
522
523     public void createNetworkPolicies(BuildingBlockExecution execution) {
524         try {
525             String fqdns = execution.getVariable(CONTRAIL_NETWORK_POLICY_FQDN_LIST);
526             if (fqdns != null && !fqdns.isEmpty()) {
527                 String fqdnList[] = fqdns.split(",");
528                 int fqdnCount = fqdnList.length;
529                 if (fqdnCount > 0) {
530                     for (int i = 0; i < fqdnCount; i++) {
531                         String fqdn = fqdnList[i];
532                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.NETWORK_POLICY);
533                         uri.queryParam(NETWORK_POLICY_FQDN_PARAM, fqdn);
534                         Optional<org.onap.aai.domain.yang.NetworkPolicy> oNetPolicy =
535                                 aaiNetworkResources.getNetworkPolicy(uri);
536                         if (!oNetPolicy.isPresent()) {
537                             logger.debug("This network policy FQDN is not in AAI yet: {}", fqdn);
538                             String networkPolicyId = UUID.randomUUID().toString();
539                             logger.debug("Adding network-policy with network-policy-id {}", networkPolicyId);
540                             NetworkPolicy networkPolicy = new NetworkPolicy();
541                             networkPolicy.setNetworkPolicyId(networkPolicyId);
542                             networkPolicy.setNetworkPolicyFqdn(fqdn);
543                             networkPolicy.setHeatStackId(execution.getVariable(HEAT_STACK_ID));
544
545                             aaiNetworkResources.createNetworkPolicy(networkPolicy);
546                         }
547                     }
548                 }
549             }
550         } catch (Exception ex) {
551             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
552         }
553     }
554
555     /**
556      * Groups existing vf modules by the model uuid of our new vf module and returns the lowest unused index
557      * 
558      * 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
559      * adding a new module type A, the vf-module-index should be 3 assuming contiguous indices (not 5, or 2)
560      * 
561      */
562     protected int getLowestUnusedVfModuleIndexFromAAIVnfResponse(GenericVnf genericVnf, VfModule newVfModule) {
563
564         String newVfModuleModelInvariantUUID = null;
565         if (newVfModule.getModelInfoVfModule() != null) {
566             newVfModuleModelInvariantUUID = newVfModule.getModelInfoVfModule().getModelInvariantUUID();
567         }
568
569
570         if (genericVnf != null && genericVnf.getVfModules() != null && !genericVnf.getVfModules().isEmpty()) {
571             List<VfModule> modules = genericVnf.getVfModules().stream()
572                     .filter(item -> !item.getVfModuleId().equals(newVfModule.getVfModuleId()))
573                     .collect(Collectors.toList());
574             TreeSet<Integer> moduleIndices = new TreeSet<>();
575             int nullIndexFound = 0;
576             for (VfModule vfModule : modules) {
577                 if (vfModule.getModelInfoVfModule() != null) {
578                     if (vfModule.getModelInfoVfModule().getModelInvariantUUID().equals(newVfModuleModelInvariantUUID)) {
579                         if (vfModule.getModuleIndex() != null) {
580                             moduleIndices.add(vfModule.getModuleIndex());
581                         } else {
582                             nullIndexFound++;
583                             logger.warn("Found null index for vf-module-id {} and model-invariant-uuid {}",
584                                     vfModule.getVfModuleId(), vfModule.getModelInfoVfModule().getModelInvariantUUID());
585                         }
586                     }
587                 }
588             }
589
590             return calculateUnusedIndex(moduleIndices, nullIndexFound);
591         } else {
592             return 0;
593         }
594     }
595
596     protected int calculateUnusedIndex(TreeSet<Integer> moduleIndices, int nullIndexFound) {
597         // pad array with nulls
598         Integer[] temp = new Integer[moduleIndices.size() + nullIndexFound];
599         Integer[] array = moduleIndices.toArray(temp);
600         int result = 0;
601         // when a null is found skip that potential value
602         // effectively creates something like, [0,1,3,null,null] -> [0,1,null(2),3,null(4)]
603         for (int i = 0; i < array.length; i++, result++) {
604             if (Integer.valueOf(result) != array[i]) {
605                 if (nullIndexFound > 0) {
606                     nullIndexFound--;
607                     i--;
608                 } else {
609                     break;
610                 }
611             }
612         }
613
614         return result;
615     }
616 }