Merge "Changed to use the physical network name"
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoCommonCoreNSSI.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2020  Telecom Italia
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.scripts
22
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.json.JSONArray
26 import org.json.JSONObject
27 import org.onap.aai.domain.yang.v19.*
28 import org.onap.aaiclient.client.aai.AAIResourcesClient
29 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
30 import org.onap.aaiclient.client.aai.entities.Relationships
31 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
32 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
34 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
35 import org.onap.logging.filter.base.ONAPComponents
36 import org.onap.so.bpmn.common.scripts.*
37 import org.onap.so.bpmn.core.UrnPropertiesReader
38 import org.onap.so.bpmn.core.json.JsonUtils
39 import org.onap.so.client.HttpClient
40 import org.onap.so.db.request.beans.ResourceOperationStatus
41 import org.onap.so.serviceinstancebeans.*
42 import org.slf4j.Logger
43 import org.slf4j.LoggerFactory
44
45 import javax.ws.rs.core.Response
46
47 import static org.apache.commons.lang3.StringUtils.isBlank
48
49 class DoCommonCoreNSSI extends AbstractServiceTaskProcessor {
50
51     private final String PREFIX ="DoCommonCoreNSSI"
52
53     private static final Logger LOGGER = LoggerFactory.getLogger( DoCommonCoreNSSI.class)
54
55     private JsonUtils jsonUtil = new JsonUtils()
56     private ExceptionUtil exceptionUtil = new ExceptionUtil()
57     private RequestDBUtil requestDBUtil = new RequestDBUtil()
58
59     @Override
60     void preProcessRequest(DelegateExecution execution) {
61         LOGGER.trace("${getPrefix()} Start preProcessRequest")
62
63         def currentNSSI = execution.getVariable("currentNSSI")
64         if (!currentNSSI) {
65             currentNSSI = [:]
66         }
67
68         // NSSI ID
69         String nssiId = execution.getVariable("serviceInstanceID")
70         if (isBlank(nssiId)) {
71             String msg = "NSSI service instance id is null"
72             LOGGER.error(msg)
73             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
74         }
75         else {
76             currentNSSI['nssiId'] = nssiId
77         }
78
79         // NSI ID
80         String nsiId = execution.getVariable("nsiId")
81         if (isBlank(nsiId)) {
82             String msg = "nsiId is null"
83             LOGGER.error(msg)
84             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
85         }
86         else {
87             currentNSSI['nsiId'] = nsiId
88         }
89
90
91         // Slice Profile
92         String sliceProfile = jsonUtil.getJsonValue(execution.getVariable("sliceParams"), "sliceProfile")
93         if (isBlank(sliceProfile)) {
94             String msg = "Slice Profile is null"
95             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
96         } else {
97             currentNSSI['sliceProfile'] = sliceProfile
98         }
99
100         // S-NSSAI
101         def snssaiList = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(sliceProfile, "snssaiList"))
102
103         String sNssai = snssaiList.get(0)
104         currentNSSI['S-NSSAI'] = sNssai
105
106
107         // Slice Profile id
108         String sliceProfileId = jsonUtil.getJsonValue(sliceProfile, "sliceProfileId")
109         currentNSSI['sliceProfileId'] = sliceProfileId
110
111         execution.setVariable("currentNSSI", currentNSSI)
112
113
114         LOGGER.trace("***** ${getPrefix()} Exit preProcessRequest")
115     }
116
117
118     /**
119      * Queries Network Service Instance in AAI
120      * @param execution
121      */
122     void getNetworkServiceInstance(DelegateExecution execution) {
123         LOGGER.trace("${getPrefix()} Start getNetworkServiceInstance")
124
125         AAIResourcesClient client = getAAIClient()
126
127         def currentNSSI = execution.getVariable("currentNSSI")
128
129         String nssiId = currentNSSI['nssiId']
130
131         AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
132         Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, nssiUri)
133
134         if (nssiOpt.isPresent()) {
135             ServiceInstance nssi = nssiOpt.get()
136             currentNSSI['nssi'] = nssi
137
138             ServiceInstance networkServiceInstance = handleNetworkInstance(execution, nssiId, nssiUri, client)
139             currentNSSI['networkServiceInstance'] = networkServiceInstance
140         }
141         else {
142             String msg = String.format("NSSI %s not found in AAI", nssiId)
143             LOGGER.error(msg)
144             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
145         }
146
147         LOGGER.trace("${getPrefix()} Exit getNetworkServiceInstance")
148     }
149
150
151     /**
152      * Handles Network Service
153      * @param nssiId
154      * @param nssiUri
155      * @param client
156      * @return Network Service Instance
157      */
158     private ServiceInstance handleNetworkInstance(DelegateExecution execution, String nssiId, AAIResourceUri nssiUri, AAIResourcesClient client ) {
159         ServiceInstance networkServiceInstance = null
160
161         def currentNSSI = execution.getVariable("currentNSSI")
162
163         AAIResultWrapper wrapper = client.get(nssiUri)
164         Optional<Relationships> relationships = wrapper.getRelationships()
165
166         if (relationships.isPresent()) {
167             for (AAIResourceUri networkServiceInstanceUri : relationships.get().getRelatedUris(Types.SERVICE_INSTANCE)) {
168                 Optional<ServiceInstance> networkServiceInstanceOpt = client.get(ServiceInstance.class, networkServiceInstanceUri)
169                 if (networkServiceInstanceOpt.isPresent()) {
170                     networkServiceInstance = networkServiceInstanceOpt.get()
171
172                     if (networkServiceInstance.getServiceRole() == "Network Service") { // Network Service role
173                         currentNSSI['networkServiceInstanceUri'] = networkServiceInstanceUri
174                         break
175                     }
176                 }
177                 else {
178                     String msg = String.format("No Network Service Instance found for NSSI %s in AAI", nssiId)
179                     LOGGER.error(msg)
180                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
181                 }
182             }
183         }
184         else {
185             String msg = String.format("No relationship presented for NSSI %s in AAI", nssiId)
186             LOGGER.error(msg)
187             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
188         }
189
190         if(networkServiceInstance == null) {
191             String msg = String.format("No Network Service Instance found for NSSI %s in AAI", nssiId)
192             LOGGER.error(msg)
193             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
194         }
195
196         return networkServiceInstance
197     }
198
199
200     /**
201      * Queries constitute VNF from Network Service Instance
202      * @param execution
203      */
204     void getConstituteVNFFromNetworkServiceInst(DelegateExecution execution) {
205         LOGGER.trace("${getPrefix()} Start getConstituteVNFFromNetworkServiceInst")
206
207         def currentNSSI = execution.getVariable("currentNSSI")
208
209         AAIResourcesClient client = getAAIClient()
210
211         AAIResourceUri networkServiceInstanceUri = (AAIResourceUri)currentNSSI['networkServiceInstanceUri']
212         AAIResultWrapper wrapper = client.get(networkServiceInstanceUri);
213         Optional<Relationships> relationships = wrapper.getRelationships()
214         if (relationships.isPresent()) {
215             for (AAIResourceUri constituteVnfUri : relationships.get().getRelatedUris(Types.GENERIC_VNF)) {
216                 currentNSSI['constituteVnfUri'] = constituteVnfUri
217                 Optional<GenericVnf> constituteVnfOpt = client.get(GenericVnf.class, constituteVnfUri)
218                 if(constituteVnfOpt.isPresent()) {
219                     GenericVnf constituteVnf = constituteVnfOpt.get()
220                     currentNSSI['constituteVnf'] = constituteVnf
221                 }
222                 else {
223                     String msg = String.format("No constitute VNF found for Network Service Instance %s in AAI", ((ServiceInstance)currentNSSI['networkServiceInstance']).getServiceInstanceId())
224                     LOGGER.error(msg)
225                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
226                 }
227
228                 break  // Should be only one constitute VNF
229             }
230         }
231         else {
232             String msg = String.format("No relationship presented for Network Service Instance %s in AAI", ((ServiceInstance)currentNSSI['networkServiceInstance']).getServiceInstanceId())
233             LOGGER.error(msg)
234             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
235         }
236
237         LOGGER.trace("${getPrefix()} Exit getConstituteVNFFromNetworkServiceInst")
238
239     }
240
241
242     /**
243      * Retrieves NSSI associated profiles from AAI
244      * @param execution
245      */
246     void getNSSIAssociatedProfiles(DelegateExecution execution) {
247         LOGGER.trace("${getPrefix()} Start getNSSIAssociatedProfiles")
248
249         def currentNSSI = execution.getVariable("currentNSSI")
250
251         ServiceInstance nssi = (ServiceInstance)currentNSSI['nssi']
252
253         List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
254
255         if(associatedProfiles.isEmpty()) {
256             String msg = String.format("No associated profiles found for NSSI %s in AAI", nssi.getServiceInstanceId())
257             LOGGER.error(msg)
258             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
259         }
260         else {
261             currentNSSI['associatedProfiles'] =  associatedProfiles
262         }
263
264         LOGGER.trace("${getPrefix()} Exit getNSSIAssociatedProfiles")
265     }
266
267
268     /**
269      * Calculates a final list of S-NSSAI
270      * @param execution
271      */
272     void calculateSNSSAI(DelegateExecution execution) {
273         LOGGER.trace("${getPrefix()} Start calculateSNSSAI")
274
275         def currentNSSI = execution.getVariable("currentNSSI")
276
277         List<SliceProfile> associatedProfiles = (List<SliceProfile>)currentNSSI['associatedProfiles']
278
279         String currentSNSSAI = currentNSSI['S-NSSAI']
280
281         List<String> snssais = new ArrayList<>()
282
283         String isCreateSliceProfileInstanceVar = execution.getVariable("isCreateSliceProfileInstance" ) // Not exist in case of Deallocate
284
285         boolean isCreateSliceProfileInstance = Boolean.parseBoolean(isCreateSliceProfileInstanceVar)
286
287         if(isCreateSliceProfileInstance) { // Slice Profile Instance has to be created
288             for (SliceProfile associatedProfile : associatedProfiles) {
289                 snssais.add(associatedProfile.getSNssai())
290             }
291
292             snssais.add(currentSNSSAI)
293         }
294         else { // Slice profile instance has to be deleted
295             for (SliceProfile associatedProfile : associatedProfiles) {
296                 if (!associatedProfile.getSNssai().equals(currentSNSSAI)) { // not current S-NSSAI
297                     snssais.add(associatedProfile.getSNssai())
298                 } else {
299                     currentNSSI['sliceProfileS-NSSAI'] = associatedProfile
300                 }
301             }
302         }
303
304         currentNSSI['S-NSSAIs'] = snssais
305
306         LOGGER.trace("${getPrefix()} Exit calculateSNSSAI")
307     }
308
309
310     /**
311      * Invoke PUT Service Instance API
312      * @param execution
313      */
314     void invokePUTServiceInstance(DelegateExecution execution) {
315         LOGGER.trace("${getPrefix()} Start invokePUTServiceInstance")
316
317         def currentNSSI = execution.getVariable("currentNSSI")
318
319         try {
320             //url:/onap/so/infra/serviceInstantiation/v7/serviceInstances/{serviceInstanceId}"
321             def nsmfЕndPoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution) // ???
322
323             ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance']
324
325             String url = String.format("${nsmfЕndPoint}/serviceInstantiation/v7/serviceInstances/%s", networkServiceInstance.getServiceInstanceId())
326
327             currentNSSI['putServiceInstanceURL'] = url
328
329             String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
330             String basicAuth =  UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
331
332             def authHeader = ""
333             String basicAuthValue = encryptBasicAuth(basicAuth, msoKey) //utils.encrypt(basicAuth, msoKey)
334             String responseAuthHeader = getAuthHeader(execution, basicAuthValue, msoKey) //utils.getBasicAuth(basicAuthValue, msoKey)
335
336             String errorCode = jsonUtil.getJsonValue(responseAuthHeader, "errorCode")
337             if(errorCode == null || errorCode.isEmpty()) { // No error
338                 authHeader = responseAuthHeader
339             }
340             else {
341                 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(responseAuthHeader, "errorMessage"))
342             }
343
344             def requestDetails = ""
345             String prepareRequestDetailsResponse = prepareRequestDetails(execution)
346             errorCode = jsonUtil.getJsonValue(prepareRequestDetailsResponse, "errorCode")
347             if(errorCode == null || errorCode.isEmpty()) { // No error
348                 requestDetails = prepareRequestDetailsResponse
349             }
350             else {
351                 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(prepareRequestDetailsResponse, "errorMessage"))
352             }
353
354             String callPUTServiceInstanceResponse = callPUTServiceInstance(url, authHeader, requestDetails)
355             String putServiceInstanceResponse = ""
356
357             if(errorCode == null || errorCode.isEmpty()) { // No error
358                 putServiceInstanceResponse = callPUTServiceInstanceResponse
359             }
360             else {
361                 LOGGER.error(jsonUtil.getJsonValue(callPUTServiceInstanceResponse, "errorMessage"))
362                 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callPUTServiceInstanceResponse, "errorMessage"))
363             }
364
365         } catch (any) {
366             String msg = "Exception in ${getPrefix()}.invokePUTServiceInstance. " + any.getCause()
367             LOGGER.error(msg)
368             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
369         }
370
371         LOGGER.trace("${getPrefix()} Exit invokePUTServiceInstance")
372     }
373
374
375     String callPUTServiceInstance(String url, String authHeader, String requestDetailsStr) {
376         String errorCode = ""
377         String errorMessage = ""
378         String response
379
380         try {
381             HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.EXTERNAL)
382             httpClient.addAdditionalHeader("Authorization", authHeader)
383             httpClient.addAdditionalHeader("Accept", "application/json")
384
385             Response httpResponse = httpClient.put(requestDetailsStr) // check http code ???
386
387
388             if (httpResponse.hasEntity()) {
389                 response = httpResponse.readEntity(String.class)
390             }
391             else {
392                 errorCode = 500
393                 errorMessage = "No response received."
394
395                 response =  "{\n" +
396                         " \"errorCode\": \"${errorCode}\",\n" +
397                         " \"errorMessage\": \"${errorMessage}\"\n" +
398                         "}"
399             }
400         }
401         catch (any) {
402             String msg = "Exception in ${getPrefix()}.invokePUTServiceInstance. " + any.getCause()
403             LOGGER.error(msg)
404
405             response =  "{\n" +
406                     " \"errorCode\": \"7000\",\n" +
407                     " \"errorMessage\": \"${msg}\"\n" +
408                     "}"
409
410         }
411
412         return response
413
414     }
415
416
417     /**
418      * Prepare model info
419      * @param execution
420      * @param requestDetails
421      * @return ModelInfo
422      */
423     ModelInfo prepareModelInfo(DelegateExecution execution) {
424
425         def currentNSSI = execution.getVariable("currentNSSI")
426         ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance']
427
428         ModelInfo modelInfo = new ModelInfo()
429
430         modelInfo.setModelType(ModelType.service)
431         modelInfo.setModelInvariantId(networkServiceInstance.getModelInvariantId())
432
433         AAIResourcesClient client = getAAIClient()
434
435         AAIResourceUri modelVerUrl = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.serviceDesignAndCreation().model(networkServiceInstance.getModelInvariantId()).modelVer(networkServiceInstance.getModelVersionId()))
436         Optional<ModelVer> modelVerOpt = client.get(ModelVer.class, modelVerUrl)
437
438         if (modelVerOpt.isPresent()) {
439             modelInfo.setModelVersionId(modelVerOpt.get().getModelVersionId())
440             modelInfo.setModelName(modelVerOpt.get().getModelName())
441             modelInfo.setModelVersion(modelVerOpt.get().getModelVersion())
442         }
443
444         return modelInfo
445     }
446
447
448     /**
449      * Prepares subscriber info
450      * @param execution
451      * @return SubscriberInfo
452      */
453     SubscriberInfo prepareSubscriberInfo(DelegateExecution execution) {
454         def currentNSSI = execution.getVariable("currentNSSI")
455
456         String globalSubscriberId = execution.getVariable("globalSubscriberId")
457
458         String subscriberName = execution.getVariable("subscriberName")
459
460         SubscriberInfo subscriberInfo = new SubscriberInfo()
461         subscriberInfo.setGlobalSubscriberId(globalSubscriberId)
462         subscriberInfo.setSubscriberName(subscriberName)
463
464         /*
465         AAIResourcesClient client = getAAIClient()
466
467         Customer customer = null
468
469         AAIResourceUri networkServiceInstanceUri = currentNSSI['networkServiceInstanceUri']
470         AAIResultWrapper wrapper = client.get(networkServiceInstanceUri)
471         Optional<Relationships> serviceSubscriptionRelationshipsOps = wrapper.getRelationships()
472         if(serviceSubscriptionRelationshipsOps.isPresent()) {
473             List<AAIResourceUri> serviceSubscriptionRelatedAAIUris = serviceSubscriptionRelationshipsOps.get().getRelatedUris(Types.SERVICE_SUBSCRIPTION)
474             if(!(serviceSubscriptionRelatedAAIUris == null || serviceSubscriptionRelatedAAIUris.isEmpty())) {
475                 AAIResourceUri serviceSubscriptionUri = serviceSubscriptionRelatedAAIUris.get(0) // Many-To-One relation
476                 Optional<ServiceSubscription> serviceSubscriptionOpt = client.get(ServiceSubscription.class, serviceSubscriptionUri)
477
478                 if(serviceSubscriptionOpt.isPresent()) {
479                     currentNSSI['serviceSubscription'] = serviceSubscriptionOpt.get()
480                 }
481
482                 wrapper = client.get(serviceSubscriptionUri)
483                 Optional<Relationships> customerRelationshipsOps = wrapper.getRelationships()
484                 if(customerRelationshipsOps.isPresent()) {
485                     List<AAIResourceUri> customerRelatedAAIUris = customerRelationshipsOps.get().getRelatedUris(Types.CUSTOMER)
486                     if(!(customerRelatedAAIUris == null || customerRelatedAAIUris.isEmpty())) {
487                         Optional<Customer> customerOpt = client.get(Customer.class, customerRelatedAAIUris.get(0)) // Many-To-One relation
488                         if(customerOpt.isPresent()) {
489                             customer = customerOpt.get()
490                             subscriberInfo.setSubscriberName(customer.getSubscriberName())
491                         }
492                     }
493                 }
494             }
495
496         } */
497
498         return subscriberInfo
499     }
500
501
502     /**
503      * Prepares Request Info
504      * @param execution
505      * @return RequestInfo
506      */
507     RequestInfo prepareRequestInfo(DelegateExecution execution, ServiceInstance networkServiceInstance) {
508         def currentNSSI = execution.getVariable("currentNSSI")
509
510         String productFamilyId = execution.getVariable("productFamilyId")
511
512         RequestInfo requestInfo = new RequestInfo()
513
514         requestInfo.setInstanceName(networkServiceInstance.getServiceInstanceName())
515         requestInfo.setSource("VID")
516         requestInfo.setProductFamilyId(productFamilyId)
517         requestInfo.setRequestorId("NBI")
518
519         return requestInfo
520     }
521
522
523     /**
524      * Prepares Model Info
525      * @param networkServiceInstance
526      * @param modelInfo
527      * @return ModelInfo
528      */
529     ModelInfo prepareServiceModelInfo(ServiceInstance networkServiceInstance, ModelInfo modelInfo) {
530
531         ModelInfo serviceModelInfo = new ModelInfo()
532         serviceModelInfo.setModelType(ModelType.service)
533         serviceModelInfo.setModelInvariantId(networkServiceInstance.getModelInvariantId())
534
535         serviceModelInfo.setModelVersionId(modelInfo.getModelVersionId())
536         serviceModelInfo.setModelName(modelInfo.getModelName())
537         serviceModelInfo.setModelVersion(modelInfo.getModelVersion())
538
539         return serviceModelInfo
540     }
541
542
543     /**
544      * Prepares Cloud configuration
545      * @param execution
546      * @return CloudConfiguration
547      */
548     CloudConfiguration prepareCloudConfiguration(DelegateExecution execution) {
549         def currentNSSI = execution.getVariable("currentNSSI")
550
551         CloudConfiguration cloudConfiguration = new CloudConfiguration()
552
553         AAIResourcesClient client = getAAIClient()
554
555         AAIResourceUri constituteVnfUri = currentNSSI['constituteVnfUri']
556         AAIResultWrapper wrapper = client.get(constituteVnfUri)
557         Optional<Relationships> cloudRegionRelationshipsOps = wrapper.getRelationships()
558
559         if(cloudRegionRelationshipsOps.isPresent()) {
560             List<AAIResourceUri> cloudRegionRelatedAAIUris = cloudRegionRelationshipsOps.get().getRelatedUris(Types.CLOUD_REGION)
561             if (!(cloudRegionRelatedAAIUris == null || cloudRegionRelatedAAIUris.isEmpty())) {
562                 AAIResourceUri cloudRegionRelatedAAIUri = cloudRegionRelatedAAIUris.get(0)
563                 currentNSSI['cloudRegionRelatedAAIUri'] = cloudRegionRelatedAAIUri
564
565                 Optional<CloudRegion> cloudRegionrOpt = client.get(CloudRegion.class, cloudRegionRelatedAAIUris.get(0))
566                 CloudRegion cloudRegion = null
567                 if (cloudRegionrOpt.isPresent()) {
568                     cloudRegion = cloudRegionrOpt.get()
569                     cloudConfiguration.setLcpCloudRegionId(cloudRegion.getCloudRegionId())
570                     for (Tenant tenant : cloudRegion.getTenants().getTenant()) {
571                         cloudConfiguration.setTenantId(tenant.getTenantId())
572                         break // only one is required
573                     }
574
575                     cloudConfiguration.setCloudOwner(cloudRegion.getCloudOwner())
576                 }
577             }
578         }
579
580         return cloudConfiguration
581     }
582
583
584     /**
585      * Prepares a list of VF Modules
586      * @param execution
587      * @param constituteVnf
588      * @return List<VfModules>
589      */
590     List<VfModules> prepareVfModules(DelegateExecution execution, GenericVnf constituteVnf) {
591
592         AAIResourcesClient client = getAAIClient()
593
594         List<VfModules> vfModuless = new ArrayList<>()
595         for (VfModule vfModule : constituteVnf.getVfModules().getVfModule()) {
596             VfModules vfmodules = new VfModules()
597
598             ModelInfo vfModuleModelInfo = new ModelInfo()
599             vfModuleModelInfo.setModelInvariantUuid(vfModule.getModelInvariantId())
600             vfModuleModelInfo.setModelCustomizationId(vfModule.getModelCustomizationId())
601
602             AAIResourceUri vfModuleUrl = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.serviceDesignAndCreation().model(vfModule.getModelInvariantId()).modelVer(vfModule.getModelVersionId()))
603
604             Optional<ModelVer> vfModuleModelVerOpt = client.get(ModelVer.class, vfModuleUrl)
605
606             if (vfModuleModelVerOpt.isPresent()) {
607                 vfModuleModelInfo.setModelVersionId(vfModuleModelVerOpt.get().getModelVersionId())
608                 vfModuleModelInfo.setModelName(vfModuleModelVerOpt.get().getModelName())
609                 vfModuleModelInfo.setModelVersion(vfModuleModelVerOpt.get().getModelVersion())
610             }
611             vfmodules.setModelInfo(vfModuleModelInfo)
612
613             vfmodules.setInstanceName(vfModule.getVfModuleName())
614
615             vfModuless.add(vfmodules)
616         }
617
618         return vfModuless
619     }
620
621
622     /**
623      * prepares VNF Model Info
624      * @param execution
625      * @param constituteVnf
626      * @return ModelInfo
627      */
628     ModelInfo prepareVNFModelInfo(DelegateExecution execution, GenericVnf constituteVnf) {
629         ModelInfo vnfModelInfo = new ModelInfo()
630
631         AAIResourcesClient client = getAAIClient()
632
633         vnfModelInfo.setModelInvariantUuid(constituteVnf.getModelInvariantId())
634         vnfModelInfo.setModelCustomizationId(constituteVnf.getModelCustomizationId())
635         vnfModelInfo.setModelInstanceName(constituteVnf.getVnfName())
636
637         AAIResourceUri vnfModelUrl = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.serviceDesignAndCreation().model(constituteVnf.getModelInvariantId()).modelVer(constituteVnf.getModelVersionId()))
638
639         Optional<ModelVer> vnfModelVerOpt = client.get(ModelVer.class, vnfModelUrl)
640
641         if (vnfModelVerOpt.isPresent()) {
642             vnfModelInfo.setModelVersionId(vnfModelVerOpt.get().getModelVersionId())
643             vnfModelInfo.setModelName(vnfModelVerOpt.get().getModelName())
644             vnfModelInfo.setModelVersion(vnfModelVerOpt.get().getModelVersion())
645         }
646
647         return vnfModelInfo
648     }
649
650
651     List<Map<String, Object>> prepareInstanceParams(DelegateExecution execution) {
652         def currentNSSI = execution.getVariable("currentNSSI")
653
654         List<Map<String, Object>> instanceParams = new ArrayList<>()
655         Map<String, Object> instanceParamsMap = new HashMap<>()
656
657         // Supported S-NSSAI
658         List<String> snssais = (List<String>) currentNSSI['S-NSSAIs']
659
660         ServiceInstance nssi = (ServiceInstance) currentNSSI['nssi']
661
662         String orchStatus = nssi.getOrchestrationStatus()
663
664
665         List<Map<String, String>> snssaiList = new ArrayList<>()
666
667         for(String snssai:snssais) {
668             Map<String, String> snssaisMap = new HashMap<>()
669             snssaisMap.put("snssai", snssai)
670             snssaisMap.put("status", orchStatus)
671             snssaiList.add(snssaisMap)
672         }
673
674         //    Map<String, List<Map<String, String>>> supportedNssaiDetails = new HashMap<>()
675         //    supportedNssaiDetails.put("sNssai", supportedNssaiDetails)
676
677         ObjectMapper mapper = new ObjectMapper()
678
679         String supportedNssaiDetailsStr = mapper.writeValueAsString(snssaiList)
680
681
682         instanceParamsMap.put("k8s-rb-profile-name", "default") // ???
683         instanceParamsMap.put("config-type", "day2") // ???
684         instanceParamsMap.put("supportedNssai", supportedNssaiDetailsStr)
685         instanceParams.add(instanceParamsMap)
686
687         return instanceParams
688     }
689
690     /**
691      * Prepares Resources
692      * @param execution
693      * @return Resources
694      */
695     Resources prepareResources(DelegateExecution execution) {
696         def currentNSSI = execution.getVariable("currentNSSI")
697
698         Resources resources = new Resources()
699
700         // VNFs
701         List<Vnfs> vnfs = new ArrayList<>()
702         // VNF
703         Vnfs vnf = new Vnfs()
704
705         // Line of Business
706         LineOfBusiness lob = new LineOfBusiness()
707         lob.setLineOfBusinessName("VNF")
708         vnf.setLineOfBusiness(lob)
709
710         // Product family ID
711         GenericVnf constituteVnf = (GenericVnf)currentNSSI['constituteVnf']
712         vnf.setProductFamilyId(constituteVnf.getServiceId())
713
714         // Cloud configuration
715         vnf.setCloudConfiguration(prepareCloudConfiguration(execution))
716
717         // VF Modules
718         vnf.setVfModules(prepareVfModules(execution, constituteVnf))
719
720         // Model Info
721         vnf.setModelInfo(prepareVNFModelInfo(execution, constituteVnf))
722
723         // Instance name
724         vnf.setInstanceName(constituteVnf.getVnfName())
725
726         // Instance params
727         vnf.setInstanceParams(prepareInstanceParams(execution))
728
729         // No platform data
730
731         vnfs.add(vnf)
732         resources.setVnfs(vnfs)
733
734         return resources
735     }
736
737
738     /**
739      * Prepare Service
740      * @return Service
741      */
742     Service prepareService(DelegateExecution execution, ServiceInstance networkServiceInstance, ModelInfo modelInfo) {
743         Service service = new Service()
744
745         // Model Info
746         service.setModelInfo(prepareServiceModelInfo(networkServiceInstance, modelInfo))
747
748         service.setInstanceName(networkServiceInstance.getServiceInstanceName())
749
750         // Resources
751         service.setResources(prepareResources(execution))
752
753         return service
754
755     }
756
757
758     /**
759      * Prepares request parameters
760      * @param execution
761      * @return RequestParameters
762      */
763     RequestParameters prepareRequestParameters(DelegateExecution execution, ServiceInstance networkServiceInstance, ModelInfo modelInfo) {
764         def currentNSSI = execution.getVariable("currentNSSI")
765
766         RequestParameters requestParameters = new RequestParameters()
767
768         ServiceSubscription serviceSubscription = (ServiceSubscription)currentNSSI['serviceSubscription']
769
770         if(serviceSubscription != null) {
771             requestParameters.setSubscriptionServiceType(serviceSubscription.getServiceType())
772         }
773
774         // User params
775         List<Map<String, Object>> userParams = new ArrayList<>()
776
777         Map<String, Object> userParam = new HashMap<>()
778         userParam.put("Homing_Solution", "none")
779         userParams.add(userParam)
780
781         // Service
782         Map<String, Object> serviceMap = new HashMap<>()
783         serviceMap.put("service", prepareService(execution, networkServiceInstance, modelInfo))
784         userParams.add(serviceMap)
785         requestParameters.setUserParams(userParams)
786
787         return requestParameters
788     }
789
790
791     /**
792      * Prepare Owning Entity
793      * @param execution
794      * @return OwningEntity
795      */
796     OwningEntity prepareOwningEntity(DelegateExecution execution) {
797         def currentNSSI = execution.getVariable("currentNSSI")
798
799         AAIResourcesClient client = getAAIClient()
800
801         AAIResourceUri networkServiceInstanceUri = (AAIResourceUri)currentNSSI['networkServiceInstanceUri']
802
803         OwningEntity owningEntity = new OwningEntity()
804         AAIResultWrapper wrapper = client.get(networkServiceInstanceUri)
805         Optional<Relationships> owningEntityRelationshipsOps = wrapper.getRelationships()
806         if (owningEntityRelationshipsOps.isPresent()) {
807             List<AAIResourceUri> owningEntityRelatedAAIUris = owningEntityRelationshipsOps.get().getRelatedUris(Types.OWNING_ENTITY)
808
809             if (!(owningEntityRelatedAAIUris == null || owningEntityRelatedAAIUris.isEmpty())) {
810                 Optional<org.onap.aai.domain.yang.OwningEntity> owningEntityOpt = client.get(org.onap.aai.domain.yang.OwningEntity.class, owningEntityRelatedAAIUris.get(0)) // Many-To-One relation
811                 if (owningEntityOpt.isPresent()) {
812                     owningEntity.setOwningEntityId(owningEntityOpt.get().getOwningEntityId())
813                     owningEntity.setOwningEntityName(owningEntityOpt.get().getOwningEntityName())
814
815                 }
816             }
817         }
818
819         return owningEntity
820     }
821
822
823     /**
824      * Prepares Project
825      * @param execution
826      * @return Project
827      */
828     Project prepareProject(DelegateExecution execution) {
829         def currentNSSI = execution.getVariable("currentNSSI")
830
831         AAIResourcesClient client = getAAIClient()
832
833         Project project = new Project()
834
835         AAIResourceUri cloudRegionRelatedAAIUri = (AAIResourceUri)currentNSSI['cloudRegionRelatedAAIUri']
836
837         if (cloudRegionRelatedAAIUri != null) {
838             AAIResultWrapper wrapper = client.get(cloudRegionRelatedAAIUri)
839             Optional<Relationships> cloudRegionOps = wrapper.getRelationships()
840             if (cloudRegionOps.isPresent()) {
841                 List<AAIResourceUri> projectAAIUris = cloudRegionOps.get().getRelatedUris(Types.PROJECT)
842                 if (!(projectAAIUris == null || projectAAIUris.isEmpty())) {
843                     Optional<org.onap.aai.domain.yang.Project> projectOpt = client.get(org.onap.aai.domain.yang.Project.class, projectAAIUris.get(0))
844                     if (projectOpt.isPresent()) {
845                         project.setProjectName(projectOpt.get().getProjectName())
846                     }
847                 }
848             }
849         }
850
851         return project
852     }
853
854
855     /**
856      * Prepares RequestDetails object
857      * @param execution
858      * @return
859      */
860     String prepareRequestDetails(DelegateExecution execution) {
861         String errorCode = ""
862         String errorMessage = ""
863         String response
864
865         RequestDetails requestDetails = new RequestDetails()
866
867         def currentNSSI = execution.getVariable("currentNSSI")
868
869         ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance']
870
871         try {
872             // Model Info
873             ModelInfo modelInfo = prepareModelInfo(execution)
874             requestDetails.setModelInfo(modelInfo)
875
876             // Subscriber Info
877             requestDetails.setSubscriberInfo(prepareSubscriberInfo(execution))
878
879             // Request Info
880             requestDetails.setRequestInfo(prepareRequestInfo(execution, networkServiceInstance))
881
882             // Request Parameters
883             requestDetails.setRequestParameters(prepareRequestParameters(execution, networkServiceInstance, modelInfo))
884
885             // Cloud configuration
886             requestDetails.setCloudConfiguration(prepareCloudConfiguration(execution))
887
888             // Owning entity
889             requestDetails.setOwningEntity(prepareOwningEntity(execution))
890
891             // Project
892             requestDetails.setProject(prepareProject(execution))
893
894             ObjectMapper mapper = new ObjectMapper()
895
896             response = mapper.writeValueAsString(requestDetails)
897         }
898         catch (any) {
899             String msg = "Exception in ${getPrefix()}.prepareRequestDetails. " + any.getCause()
900             LOGGER.error(msg)
901
902             response =  "{\n" +
903                     " \"errorCode\": \"7000\",\n" +
904                     " \"errorMessage\": \"${msg}\"\n" +
905                     "}"
906
907         }
908
909         return response
910     }
911
912
913     String getAuthHeader(DelegateExecution execution, String basicAuthValue, String msokey) {
914         String response = ""
915         String errorCode = ""
916         String errorMessage = ""
917
918         LOGGER.debug("Obtained BasicAuth username and password for OOF: " + basicAuthValue)
919         try {
920             response = utils.getBasicAuth(basicAuthValue, msokey)
921         } catch (Exception ex) {
922             LOGGER.error("Unable to encode username and password string: ", ex)
923
924             errorCode = "401"
925             errorMessage = "Internal Error - Unable to encode username and password string"
926
927             response =  "{\n" +
928                     " \"errorCode\": \"${errorCode}\",\n" +
929                     " \"errorMessage\": \"${errorMessage}\"\n" +
930                     "}"
931         }
932
933         return response
934     }
935
936
937     String encryptBasicAuth(String basicAuth, String msoKey) {
938         return utils.encrypt(basicAuth, msoKey)
939     }
940
941
942     /**
943      * Removes Slice Profile association with NSSI
944      * @param execution
945      */
946     void removeSPAssociationWithNSSI(DelegateExecution execution) {
947         LOGGER.trace("${getPrefix()} Start removeSPAssociationWithNSSI")
948
949         AAIResourcesClient client = getAAIClient()
950
951         def currentNSSI = execution.getVariable("currentNSSI")
952
953         ServiceInstance nssi = (ServiceInstance)currentNSSI['nssi']
954
955         String nssiId = currentNSSI['nssiId']
956         AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
957
958         List<SliceProfile> associatedProfiles = nssi.getSliceProfiles().getSliceProfile()
959
960         String currentSNSSAI = currentNSSI['S-NSSAI']
961
962         associatedProfiles.removeIf({ associatedProfile -> (associatedProfile.getSNssai().equals(currentSNSSAI)) })
963
964         try {
965             getAAIClient().update(nssiUri, nssi)
966         }catch(Exception e){
967             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile association with NSSI update call: " + e.getMessage())
968         }
969
970         LOGGER.trace("${getPrefix()} Exit removeSPAssociationWithNSSI")
971     }
972
973
974     /**
975      * Deletes Slice Profile Instance
976      * @param execution
977      */
978     void deleteSliceProfileInstance(DelegateExecution execution) {
979         LOGGER.trace("${getPrefix()} Start deleteSliceProfileInstance")
980
981         AAIResourcesClient client = getAAIClient()
982
983         def currentNSSI = execution.getVariable("currentNSSI")
984
985         SliceProfile sliceProfileContainsSNSSAI = (SliceProfile)currentNSSI['sliceProfileS-NSSAI']
986
987         String globalSubscriberId = execution.getVariable("globalSubscriberId")
988         String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
989         String nssiId = currentNSSI['nssiId']
990
991         // global-customer-id, service-type, service-instance-id, profile-id
992         AAIResourceUri sliceProfileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(nssiId).sliceProfile(sliceProfileContainsSNSSAI.getProfileId()))
993
994         try {
995             client.delete(sliceProfileUri)
996         }catch(Exception e){
997             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while Slice Profile Instance delete call: " + e.getMessage())
998         }
999
1000         LOGGER.trace("${getPrefix()} Exit deleteSliceProfileInstance")
1001     }
1002
1003
1004     /**
1005      * Prepares update resource operation status
1006      * @param execution
1007      */
1008     void prepareUpdateResourceOperationStatus(DelegateExecution execution) {
1009         LOGGER.trace("${getPrefix()} Start updateServiceOperationStatus")
1010
1011         def currentNSSI = execution.getVariable("currentNSSI")
1012
1013         //Prepare Update Status for PUT failure and success
1014         String isTimeOutVar = execution.getVariable("isTimeOut")
1015         if(!isBlank(isTimeOutVar) && isTimeOutVar.equals("YES")) {
1016             LOGGER.error("TIMEOUT - SO PUT Failure")
1017             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "SO PUT Failure")
1018         } else {
1019             execution.setVariable("progress", "100")
1020             execution.setVariable("status", "finished")
1021             execution.setVariable("operationContent", "${getAction()} Core NSSI successful.")
1022         }
1023
1024         setResourceOperationStatus(execution, "finished", "100", "Core NSSI ${getAction()} successful")
1025
1026         LOGGER.trace("${getPrefix()} Exit updateServiceOperationStatus")
1027     }
1028
1029
1030     /**
1031      * Prepares ResourceOperation status
1032      * @param execution
1033      * @param operationType
1034      */
1035     void setResourceOperationStatus(DelegateExecution execution, String status, String progress, String statusDesc) {
1036         LOGGER.trace("${getPrefix()} Start setResourceOperationStatus")
1037
1038         def currentNSSI = execution.getVariable("currentNSSI")
1039
1040         String serviceId = currentNSSI['nssiId']
1041         String jobId = execution.getVariable("jobId")
1042         String nsiId = currentNSSI['nsiId']
1043         String operationType = execution.getVariable("operationType")
1044
1045         ResourceOperationStatus resourceOperationStatus = new ResourceOperationStatus()
1046         resourceOperationStatus.setServiceId(serviceId)
1047         resourceOperationStatus.setOperationId(jobId)
1048         resourceOperationStatus.setResourceTemplateUUID(nsiId)
1049         resourceOperationStatus.setOperType(operationType)
1050         resourceOperationStatus.setStatus(status)
1051         resourceOperationStatus.setProgress(progress)
1052         resourceOperationStatus.setStatusDescription(statusDesc)
1053         requestDBUtil.prepareUpdateResourceOperationStatus(execution, resourceOperationStatus)
1054
1055         LOGGER.trace("${getPrefix()} Exit setResourceOperationStatus")
1056     }
1057
1058
1059     /**
1060      * Prepares failed operation status update
1061      * @param execution
1062      */
1063     void prepareFailedOperationStatusUpdate(DelegateExecution execution) {
1064         LOGGER.trace("${getPrefix()} Start prepareFailedOperationStatusUpdate")
1065
1066         setResourceOperationStatus(execution, "failed", "0", "Core NSSI ${getAction()} Failed")
1067
1068         LOGGER.trace("${getPrefix()} Exit prepareFailedOperationStatusUpdate")
1069     }
1070
1071
1072     /**
1073      * Gets progress status of ServiceInstance PUT operation
1074      * @param execution
1075      */
1076     public void getPUTServiceInstanceProgress(DelegateExecution execution) {
1077         LOGGER.trace("${getPrefix()} Start getPUTServiceInstanceProgress")
1078
1079         def currentNSSI = execution.getVariable("currentNSSI")
1080
1081         String url = currentNSSI['putServiceInstanceURL']
1082
1083         getProgress(execution, url, "putStatus")
1084
1085         LOGGER.trace("${getPrefix()} Exit getPUTServiceInstanceProgress")
1086     }
1087
1088
1089     void getProgress(DelegateExecution execution, String url, String statusVariableName) {
1090         String msg=""
1091         try {
1092
1093             ExternalAPIUtil externalAPIUtil = getExternalAPIUtilFactory().create()
1094             Response response = externalAPIUtil.executeExternalAPIGetCall(execution, url)
1095             int responseCode = response.getStatus()
1096             execution.setVariable("GetServiceOrderResponseCode", responseCode)
1097             LOGGER.debug("Get ServiceOrder response code is: " + responseCode)
1098
1099             String extApiResponse = response.readEntity(String.class)
1100             JSONObject responseObj = new JSONObject(extApiResponse)
1101             execution.setVariable("GetServiceOrderResponse", extApiResponse)
1102             LOGGER.debug("Create response body is: " + extApiResponse)
1103             //Process Response //200 OK 201 CREATED 202 ACCEPTED
1104             if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
1105             {
1106                 LOGGER.debug("Get Create ServiceOrder Received a Good Response")
1107                 String orderState = responseObj.get("state")
1108                 if("REJECTED".equalsIgnoreCase(orderState)) {
1109                     prepareFailedOperationStatusUpdate(execution)
1110                     return
1111                 }
1112
1113                 JSONArray items = responseObj.getJSONArray("orderItem")
1114                 JSONObject item = items.get(0)
1115                 JSONObject service = item.get("service")
1116                 String networkServiceId = service.get("id")
1117                 if (networkServiceId == null || networkServiceId.equals("null")) {
1118                     prepareFailedOperationStatusUpdate(execution)
1119                     return
1120                 }
1121
1122                 execution.setVariable("networkServiceId", networkServiceId)
1123                 String serviceOrderState = item.get("state")
1124                 execution.setVariable("ServiceOrderState", serviceOrderState)
1125                 // Get serviceOrder State and process progress
1126                 if("ACKNOWLEDGED".equalsIgnoreCase(serviceOrderState)) {
1127                     execution.setVariable(statusVariableName, "processing")
1128                 }
1129                 else if("INPROGRESS".equalsIgnoreCase(serviceOrderState)) {
1130                     execution.setVariable(statusVariableName, "processing")
1131                 }
1132                 else if("COMPLETED".equalsIgnoreCase(serviceOrderState)) {
1133                     execution.setVariable(statusVariableName, "completed")
1134                 }
1135                 else if("FAILED".equalsIgnoreCase(serviceOrderState)) {
1136                     msg = "ServiceOrder failed"
1137                     exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  msg)
1138                 }
1139                 else {
1140                     msg = "ServiceOrder failed"
1141                     exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  msg)
1142                 }
1143             }
1144             else{
1145                 msg = "Get ServiceOrder Received a Bad Response Code. Response Code is: " + responseCode
1146                 prepareFailedOperationStatusUpdate(execution)
1147             }
1148
1149         }catch(Exception e){
1150             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  e.getMessage())
1151         }
1152
1153     }
1154
1155
1156
1157     /**
1158      * Delays 5 sec
1159      * @param execution
1160      */
1161     void timeDelay(DelegateExecution execution) {
1162         LOGGER.trace("${getPrefix()} Start timeDelay")
1163
1164         try {
1165             LOGGER.debug("${getPrefix()} timeDelay going to sleep for 5 sec")
1166
1167             Thread.sleep(5000)
1168
1169             LOGGER.debug("${getPrefix()} ::: timeDelay wakeup after 5 sec")
1170         } catch(InterruptedException e) {
1171             LOGGER.error("${getPrefix()} ::: timeDelay exception" + e)
1172         }
1173
1174         LOGGER.trace("${getPrefix()} Exit timeDelay")
1175     }
1176
1177
1178     /**
1179      * Returns AAI client
1180      * @return AAI client
1181      */
1182     AAIResourcesClient getAAIClient() {
1183         return new AAIResourcesClient()
1184     }
1185
1186
1187     ExternalAPIUtilFactory getExternalAPIUtilFactory() {
1188         return new ExternalAPIUtilFactory()
1189     }
1190
1191
1192     String getPrefix() {
1193         return PREFIX
1194     }
1195
1196     String getAction() {
1197         return ""
1198     }
1199 }