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