Merge branch 'recursive-orch'
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeallocateCoreNSSI.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.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.json.JSONArray
27 import org.json.JSONObject
28 import org.onap.aai.domain.yang.v19.ModelVer
29 import org.onap.aai.domain.yang.v19.ServiceInstance
30 import org.onap.aai.domain.yang.v19.SliceProfile
31 import org.onap.aaiclient.client.aai.AAIResourcesClient
32 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
33 import org.onap.aaiclient.client.aai.entities.Relationships
34 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
35 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
37 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
38 import org.onap.logging.filter.base.ONAPComponents
39 import org.onap.so.bpmn.common.scripts.ExceptionUtil
40 import org.onap.so.bpmn.common.scripts.ExternalAPIUtil
41 import org.onap.so.bpmn.common.scripts.ExternalAPIUtilFactory
42 import org.onap.so.bpmn.common.scripts.MsoUtils
43 import org.onap.so.bpmn.common.scripts.OofUtils
44 import org.onap.so.bpmn.common.scripts.RequestDBUtil
45 import org.onap.so.bpmn.core.UrnPropertiesReader
46 import org.onap.so.bpmn.core.json.JsonUtils
47 import org.onap.so.client.HttpClient
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
50
51 import javax.ws.rs.core.Response
52
53 import static org.onap.so.bpmn.common.scripts.GenericUtils.isBlank
54
55 class DoDeallocateCoreNSSI extends DoCommonCoreNSSI {
56     private final String PREFIX ="DoDeallocateCoreNSSI"
57     private final  String ACTION = "Deallocate"
58
59     private ExceptionUtil exceptionUtil = new ExceptionUtil()
60     private RequestDBUtil requestDBUtil = new RequestDBUtil()
61     private MsoUtils utils = new MsoUtils()
62     private JsonUtils jsonUtil = new JsonUtils()
63
64     private static final Logger LOGGER = LoggerFactory.getLogger( DoDeallocateCoreNSSI.class)
65
66
67     @Override
68     void preProcessRequest(DelegateExecution execution) {
69         LOGGER.debug("${getPrefix()} Start preProcessRequest")
70
71         super.preProcessRequest(execution)
72
73         execution.setVariable("operationType", "DEALLOCATE")
74
75         LOGGER.debug("${getPrefix()} Exit preProcessRequest")
76     }
77
78
79
80     /**
81      * Queries OOF for NSSI termination
82      * @param execution
83      */
84     void executeTerminateNSSIQuery(DelegateExecution execution) {
85         LOGGER.debug("${PREFIX} Start executeTerminateNSSIQuery")
86
87         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
88
89         //API Path
90         String apiPath =  "/api/oof/terminate/nxi/v1"
91         LOGGER.debug("API path for DoAllocateCoreNSSI: "+apiPath)
92
93         urlString = urlString + apiPath
94
95         //Prepare auth for OOF
96         def authHeader = ""
97         String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
98         String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
99
100         String basicAuthValue = utils.encrypt(basicAuth, msokey)
101
102         try {
103             authHeader = utils.getBasicAuth(basicAuthValue, msokey)
104             execution.setVariable("BasicAuthHeaderValue", authHeader)
105         } catch (Exception ex) {
106             LOGGER.error( "Unable to encode username and password string: " + ex)
107             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to encode username and password string")
108         }
109
110         //Prepare send request to OOF
111         String oofRequest = buildOOFRequest(execution)
112
113         String callOOFResponse = callOOF(urlString, authHeader, oofRequest)
114         LOGGER.debug("callOOFResponse=" + callOOFResponse)
115
116         String errorCode = jsonUtil.getJsonValue(callOOFResponse, "errorCode")
117         if(errorCode == null || errorCode.isEmpty()) { // No error
118             String terminateNSSI = jsonUtil.getJsonValue(callOOFResponse, "terminateResponse")
119             LOGGER.debug("isTerminateNSSI=" + terminateNSSI)
120
121             execution.setVariable("isTerminateNSSI", terminateNSSI)
122         }
123         else {
124             LOGGER.error(jsonUtil.getJsonValue(callOOFResponse, "errorMessage"))
125             exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callOOFResponse, "errorMessage"))
126         }
127
128         LOGGER.debug("${PREFIX} Exit executeTerminateNSSIQuery")
129     }
130
131
132     /**
133      * Executes sync call to OOF
134      * @return OOF response
135      */
136     String callOOF(String urlString, String authHeader, String oofRequest) {
137         LOGGER.debug("${PREFIX} Start callOOF")
138
139         String errorCode = ""
140         String errorMessage = ""
141         String response = ""
142
143         try {
144             URL url = new URL(urlString)
145             HttpClient httpClient = getHttpClientFactory().newJsonClient(url, ONAPComponents.OOF)
146             httpClient.addAdditionalHeader("Authorization", authHeader)
147             httpClient.addAdditionalHeader("Content-Type", "application/json")
148
149             Response httpResponse = httpClient.post(oofRequest)
150
151             int responseCode = httpResponse.getStatus()
152             LOGGER.debug("OOF sync response code is: " + responseCode)
153
154             if(responseCode < 200 || responseCode >= 300) { // Wrong code
155                 errorCode = responseCode
156                 errorMessage = "Received a Bad Sync Response from OOF."
157
158                 response =  "{\n" +
159                         " \"errorCode\": \"${errorCode}\",\n" +
160                         " \"errorMessage\": \"${errorMessage}\"\n" +
161                         "}"
162             }
163
164             if (httpResponse.hasEntity()) {
165                 response = httpResponse.readEntity(String.class)
166             }
167             else {
168                 errorCode = 500
169                 errorMessage = "No response received from OOF."
170
171                 response =  "{\n" +
172                         " \"errorCode\": \"${errorCode}\",\n" +
173                         " \"errorMessage\": \"${errorMessage}\"\n" +
174                         "}"
175             }
176         }
177         catch(Exception e) {
178             errorCode = 400
179             errorMessage = e.getMessage()
180
181             response =  "{\n" +
182                     " \"errorCode\": \"${errorCode}\",\n" +
183                     " \"errorMessage\": \"${errorMessage}\"\n" +
184                     "}"
185         }
186
187         LOGGER.debug("${PREFIX} Exit callOOF")
188
189         return response
190     }
191
192
193     /**
194      * Builds OOF request
195      * @param execution
196      * @return
197      */
198     private String buildOOFRequest(DelegateExecution execution) {
199         LOGGER.debug("${PREFIX} Start buildOOFRequest")
200
201         def currentNSSI = execution.getVariable("currentNSSI")
202
203         String nssiId = currentNSSI['nssiId']
204
205         ServiceInstance nssi = null
206
207         AAIResourcesClient client = getAAIClient()
208
209         // NSSI
210         AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
211         Optional<ServiceInstance> nssiOpt = client.get(ServiceInstance.class, nssiUri)
212
213         if (nssiOpt.isPresent()) {
214             nssi = nssiOpt.get()
215         }
216         else {
217             String msg = "NSSI service instance not found in AAI for nssi id " + nssiId
218             LOGGER.error(msg)
219             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
220         }
221
222
223         // NSI
224         String nsiId = currentNSSI['nsiId']
225         ServiceInstance nsi = null
226         AAIResourceUri nsiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nsiId))
227         Optional<ServiceInstance> nsiOpt = client.get(ServiceInstance.class, nsiUri)
228         if (nsiOpt.isPresent()) {
229             nsi = nsiOpt.get()
230         }
231         else {
232             String msg = "NSI service instance not found in AAI for nsi id " + nsiId
233             LOGGER.error(msg)
234             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
235         }
236
237
238         //Setting correlator as requestId
239         String requestId = execution.getVariable("msoRequestId")
240         execution.setVariable("NSSI_correlator", requestId)
241
242         //Setting messageType for all Core slice as cn
243         String messageType = "cn"
244         execution.setVariable("NSSI_messageType", messageType)
245
246         //Prepare Callback
247         String timeout = execution.getVariable("timeout")
248         if (isBlank(timeout)) {
249             timeout = UrnPropertiesReader.getVariable("mso.oof.timeout", execution);
250             if (isBlank(timeout)) {
251                 timeout = "PT30M"
252             }
253         }
254
255         String nxlId = nssi.getServiceInstanceId()
256         String nxlType = "NSSI"
257         String oofRequest = getOofUtils().buildTerminateNxiRequest(requestId, nxlId, nxlType, messageType, nsi.getServiceInstanceId())
258         LOGGER.debug("**** Terminate Nxi Request: "+oofRequest)
259
260         LOGGER.debug("${PREFIX} Exit buildOOFRequest")
261
262         return oofRequest
263     }
264
265
266     /**
267      * Prepares ServiceOrderRequest
268      * @param execution
269      */
270     private void prepareServiceOrderRequest(DelegateExecution execution) {
271         LOGGER.debug("${PREFIX} Start prepareServiceOrderRequest")
272
273         def currentNSSI = execution.getVariable("currentNSSI")
274
275         //extAPI path hardcoded for testing purposes, will be updated in next patch
276         String extAPIPath = "https://nbi.onap:8443/nbi/api/v4" + "/serviceOrder"
277         execution.setVariable("ExternalAPIURL", extAPIPath)
278         ObjectMapper objectMapper = new ObjectMapper();
279         Map<String, Object> serviceOrder = new LinkedHashMap()
280         //ExternalId
281         serviceOrder.put("externalId", "ONAP001")
282
283         //Requested Start Date
284         String requestedStartDate = utils.generateCurrentTimeInUtc()
285         String requestedCompletionDate = utils.generateCurrentTimeInUtc()
286         serviceOrder.put("requestedStartDate", requestedStartDate)
287         serviceOrder.put("requestedCompletionDate", requestedCompletionDate)
288
289         //RelatedParty Fields
290         String relatedPartyId = execution.getVariable("globalSubscriberId")
291         String relatedPartyRole = "ONAPcustomer"
292         Map<String, String> relatedParty = new LinkedHashMap()
293         relatedParty.put("id", relatedPartyId)
294         relatedParty.put("role", relatedPartyRole)
295         List<Map<String, String>> relatedPartyList = new ArrayList()
296         relatedPartyList.add(relatedParty)
297         serviceOrder.put("relatedParty", relatedPartyList)
298
299         Map<String, Object> orderItem = new LinkedHashMap()
300         //orderItem id
301         String orderItemId = "1"
302         orderItem.put("id", orderItemId)
303
304         //order item action will always be delete as we are triggering request for deletion
305         String orderItemAction = "delete"
306         orderItem.put("action", orderItemAction)
307
308         // service Details
309         AAIResourcesClient client = getAAIClient()
310         ServiceInstance networkServiceInstance = (ServiceInstance)currentNSSI['networkServiceInstance'] //(ServiceInstance) currentNSSI['nssi']
311         AAIResourceUri modelVerUrl = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.serviceDesignAndCreation().model(networkServiceInstance.getModelInvariantId()).modelVer(networkServiceInstance.getModelVersionId()))
312
313         Map<String, Object> service = new LinkedHashMap()
314         // Service id
315         service.put("id",  networkServiceInstance.getServiceInstanceId())
316
317         //ServiceName
318         String serviceName = networkServiceInstance.getServiceInstanceName()
319         service.put("name",  serviceName)
320
321         // Service Type
322         service.put("serviceType", networkServiceInstance.getServiceType())
323         //Service State
324         service.put("serviceState", "active")
325
326         Map<String, String> serviceSpecification = new LinkedHashMap()
327         String modelUuid = networkServiceInstance.getModelVersionId()
328         serviceSpecification.put("id", modelUuid)
329         service.put("serviceSpecification", serviceSpecification)
330
331         orderItem.put("service", service)
332         List<Map<String, String>> orderItemList = new ArrayList()
333         orderItemList.add(orderItem)
334         serviceOrder.put("orderItem", orderItemList)
335         String jsonServiceOrder = objectMapper.writeValueAsString(serviceOrder)
336         LOGGER.debug("******* ServiceOrder :: "+jsonServiceOrder)
337         execution.setVariable("serviceOrderRequest", jsonServiceOrder)
338
339         LOGGER.debug("${PREFIX} End prepareServiceOrderRequest")
340     }
341
342
343
344     /**
345      * Invokes deleteServiceOrder external API
346      * @param execution
347      */
348     void deleteServiceOrder(DelegateExecution execution) {
349         LOGGER.debug("${PREFIX} Start deleteServiceOrder")
350
351         def currentNSSI = execution.getVariable("currentNSSI")
352
353         prepareServiceOrderRequest(execution)
354
355         try {
356             String extAPIPath = execution.getVariable("ExternalAPIURL")
357             String payload = execution.getVariable("serviceOrderRequest")
358             LOGGER.debug("externalAPIURL is: " + extAPIPath)
359             LOGGER.debug("ServiceOrder payload is: " + payload)
360
361             execution.setVariable("ServiceOrderId", "")
362
363             String callDeleteServiceOrderResponse = callDeleteServiceOrder(execution, extAPIPath, payload)
364             String errorCode = jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorCode")
365
366             if(errorCode == null || errorCode.isEmpty()) { // No error
367                 JSONObject responseObj = new JSONObject(callDeleteServiceOrderResponse)
368
369                 String serviceOrderId = responseObj.get("id")
370
371                 execution.setVariable("ServiceOrderId", serviceOrderId)
372                 LOGGER.info("Delete ServiceOrderid is: " + serviceOrderId)
373             }
374             else {
375                 LOGGER.error(jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
376                 exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(errorCode), jsonUtil.getJsonValue(callDeleteServiceOrderResponse, "errorMessage"))
377             }
378
379         }catch (BpmnError e) {
380             throw e;
381         } catch (Exception ex) {
382             String msg = "Exception in ServiceOrder ExtAPI" + ex.getMessage()
383             LOGGER.debug(msg)
384             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
385         }
386
387         LOGGER.debug("${PREFIX} Exit deleteServiceOrder")
388     }
389
390
391     String callDeleteServiceOrder(DelegateExecution execution, String extAPIPath, String payload) {
392         LOGGER.debug("${PREFIX} Start callDeleteServiceOrder")
393
394         String errorCode = ""
395         String errorMessage = ""
396         String response = ""
397
398         LOGGER.debug("callDeleteServiceOrder: url = " + extAPIPath)
399
400         try {
401             ExternalAPIUtil externalAPIUtil = getExternalAPIUtil()
402             Response httpResponse = externalAPIUtil.executeExternalAPIPostCall(execution, extAPIPath, payload)
403
404             int responseCode = httpResponse.getStatus()
405             execution.setVariable("ServiceOrderResponseCode", responseCode)
406             LOGGER.debug("Delete ServiceOrder response code is: " + responseCode)
407
408             //Process Response
409             if(responseCode == 200 || responseCode == 201 || responseCode == 202 ) {
410             //200 OK 201 CREATED 202 ACCEPTED
411                 LOGGER.debug("Delete ServiceOrder Received a Good Response")
412
413                 response = httpResponse.readEntity(String.class)
414
415                 LOGGER.debug("callDeleteServiceInstance: response = " + response)
416
417                 execution.setVariable("DeleteServiceOrderResponse", response)
418
419             }
420             else {
421                 errorCode = 500
422                 errorMessage = "Response code is " + responseCode
423
424                 response =  "{\n" +
425                         " \"errorCode\": \"${errorCode}\",\n" +
426                         " \"errorMessage\": \"${errorMessage}\"\n" +
427                         "}"
428             }
429         }
430         catch (any) {
431             String msg = "Exception in DoDeallocateCoreNSSI.callDeleteServiceOrder. " + any.getCause()
432
433             response =  "{\n" +
434                     " \"errorCode\": \"7000\",\n" +
435                     " \"errorMessage\": \"${msg}\"\n" +
436                     "}"
437         }
438
439         LOGGER.debug("${PREFIX} Exit callDeleteServiceOrder")
440
441         return response
442     }
443
444
445     /**
446      * Removes NSSI association with NSI
447      * @param execution
448      */
449     void removeNSSIAssociationWithNSI(DelegateExecution execution) {
450         LOGGER.debug("${PREFIX} Start removeNSSIAssociationWithNSI")
451
452         AAIResourcesClient client = getAAIClient()
453
454         def currentNSSI = execution.getVariable("currentNSSI")
455
456         String nssiId = currentNSSI['nssiId']
457         String nsiId = currentNSSI['nsiId']
458         String globalSubscriberId = execution.getVariable("globalSubscriberId")
459         String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
460
461         // NSSI
462         AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
463
464
465         String allottedResourceId = null
466
467
468         AAIResultWrapper nssiWrapper = client.get(nssiUri)
469         Optional<Relationships> nssiRelationships = nssiWrapper.getRelationships()
470
471         if (nssiRelationships.isPresent()) {
472             // Allotted Resource
473             for (AAIResourceUri allottedResourceUri : nssiRelationships.get().getRelatedUris(Types.ALLOTTED_RESOURCE)) {
474                 AAIResultWrapper arWrapper = client.get(allottedResourceUri)
475                 Optional<Relationships> arRelationships = arWrapper.getRelationships()
476
477                 if(arRelationships.isPresent()) {
478                     // NSI
479                     for (AAIResourceUri nsiUri : arRelationships.get().getRelatedUris(Types.SERVICE_INSTANCE)) {
480                         Optional<ServiceInstance> nsiOpt = client.get(ServiceInstance.class, nsiUri)
481
482                         if (nsiOpt.isPresent()) {
483                             ServiceInstance nsi = nsiOpt.get()
484                             if(nsi.getServiceRole().equals("nsi")) { // Service instance as NSI
485                                 // Removes NSSI association with NSI
486                                 try {
487                                     client.disconnect(nssiUri, nsiUri)
488                                 }
489                                 catch (Exception e) {
490                                     exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occured while NSSI association with NSI dosconnect call: " + e.getMessage())
491                                 }
492                             }
493                         }
494                         else {
495                             LOGGER.warn("No NSI found for NSSI id " + nssiId)
496                         }
497                     }
498                 }
499                 else {
500                     LOGGER.warn("No relationships found for Allotted Resource for NSSI id " + nssiId)
501                 }
502
503             }
504         }
505         else {
506             LOGGER.warn("No relationships  found for nssi id = " + nssiId)
507         }
508
509
510         LOGGER.debug("${PREFIX} Exit removeNSSIAssociationWithNSI")
511     }
512
513
514     /**
515      * Delets NSSI Service Instance
516      * @param execution
517      */
518     void deleteNSSIServiceInstance(DelegateExecution execution) {
519         LOGGER.debug("${PREFIX} Start deleteNSSIServiceInstance")
520
521         AAIResourcesClient client = getAAIClient()
522
523         def currentNSSI = execution.getVariable("currentNSSI")
524
525         String nssiId = currentNSSI['nssiId']
526         AAIResourceUri nssiUri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(nssiId))
527
528         try {
529             client.delete(nssiUri)
530         }catch(Exception e){
531             exceptionUtil.buildAndThrowWorkflowException(execution, 25000, "Exception occurred while NSSI Service Instance delete call: " + e.getMessage())
532         }
533
534         LOGGER.debug("${PREFIX} Exit deleteNSSIServiceInstance")
535     }
536
537
538     /**
539      * Gets Delete Service Order progress
540      * @param execution
541      */
542     void getDeleteServiceOrderProgress(DelegateExecution execution) {
543         LOGGER.debug("${getPrefix()} Start getDeleteServiceOrderProgress")
544
545         String msg
546         try {
547             String extAPIPath = execution.getVariable("ExternalAPIURL")
548             extAPIPath += "/" + execution.getVariable("ServiceOrderId")
549             LOGGER.debug("externalAPIURL is: " + extAPIPath)
550
551             ExternalAPIUtil externalAPIUtil = getExternalAPIUtil()
552             Response response = externalAPIUtil.executeExternalAPIGetCall(execution, extAPIPath)
553             int responseCode = response.getStatus()
554             execution.setVariable("GetServiceOrderResponseCode", responseCode)
555             LOGGER.debug("Get ServiceOrder response code is: " + responseCode)
556             String extApiResponse = response.readEntity(String.class)
557             JSONObject responseObj = new JSONObject(extApiResponse)
558             execution.setVariable("GetServiceOrderResponse", extApiResponse)
559             LOGGER.debug("Get response body is: " + extApiResponse)
560             //Process Response //200 OK 201 CREATED 202 ACCEPTED
561             if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
562             {
563                 LOGGER.debug("Get Delete ServiceOrder Received a Good Response")
564                 String orderState = responseObj.get("state")
565                 if("REJECTED".equalsIgnoreCase(orderState)) {
566                     prepareFailedOperationStatusUpdate(execution)
567                     return
568                 }
569                 JSONArray items = responseObj.getJSONArray("orderItem")
570                 JSONObject item = items.get(0) as JSONObject
571                 JSONObject service = item.get("service") as JSONObject
572                 String networkServiceId = service.get("id")
573
574                 execution.setVariable("networkServiceId", networkServiceId)
575                 String serviceOrderState = item.get("state")
576                 execution.setVariable("ServiceOrderState", serviceOrderState)
577                 // Get serviceOrder State and process progress
578                 if("ACKNOWLEDGED".equalsIgnoreCase(serviceOrderState) || "INPROGRESS".equalsIgnoreCase(serviceOrderState) || "IN_PROGRESS".equalsIgnoreCase(serviceOrderState)) {
579                     execution.setVariable("deleteStatus", "processing")
580                 }
581                 else if("COMPLETED".equalsIgnoreCase(serviceOrderState)) {
582                     execution.setVariable("deleteStatus", "completed")
583                 }
584                 else if("FAILED".equalsIgnoreCase(serviceOrderState)) {
585                     msg = "ServiceOrder failed"
586                     exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  msg)
587                 }
588                 else {
589                     msg = "ServiceOrder failed"
590                     exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  msg)
591                 }
592                 LOGGER.debug("NBI serviceOrder state: "+serviceOrderState)
593             }
594             else{
595                 msg = "Get ServiceOrder Received a Bad Response Code. Response Code is: " + responseCode
596                 prepareFailedOperationStatusUpdate(execution)
597                 exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  msg)
598             }
599
600         }catch(Exception e){
601             exceptionUtil.buildAndThrowWorkflowException(execution, 7000,  e.getMessage())
602         }
603
604         LOGGER.debug("${getPrefix()} Exit getDeleteServiceOrderProgress")
605     }
606
607
608     /**
609      * Calculates a final list of S-NSSAI
610      * @param execution
611      */
612     void calculateSNSSAI(DelegateExecution execution) {
613         LOGGER.debug("${getPrefix()} Start calculateSNSSAI")
614
615         def currentNSSI = execution.getVariable("currentNSSI")
616
617         List<SliceProfile> associatedProfiles = (List<SliceProfile>)currentNSSI['associatedProfiles']
618
619         String givenSliceProfileId = currentNSSI['sliceProfileId']
620
621         List<String> snssais = new ArrayList<>()
622
623         String isTerminateNSSIVar = execution.getVariable("isTerminateNSSI" )
624
625         boolean isTerminateNSSI = Boolean.parseBoolean(isTerminateNSSIVar)
626
627         if(!isTerminateNSSI) { // NSSI should not be terminated
628             LOGGER.debug("calculateSNSSAI: associatedProfiles.size()" + associatedProfiles.size())
629             for (SliceProfile associatedProfile : associatedProfiles) {
630                 if (!associatedProfile.getProfileId().equals(givenSliceProfileId)) { // not given profile id
631                     LOGGER.debug("calculateSNSSAI: associatedProfile.getSNssai()" + associatedProfile.getSNssai())
632                     snssais.add(associatedProfile.getSNssai())
633                 } else {
634                     currentNSSI['sliceProfileS-NSSAI'] = associatedProfile
635                 }
636             }
637         }
638
639         currentNSSI['S-NSSAIs'] = snssais
640
641         LOGGER.debug("${getPrefix()} Exit calculateSNSSAI")
642     }
643
644
645     /**
646      * OofUtils
647      * @return new OofUtils()
648      */
649     OofUtils getOofUtils() {
650         return new OofUtils()
651     }
652
653
654     private String getPrefix() {
655         return PREFIX
656     }
657
658     @Override
659     String getAction() {
660         return ACTION
661     }
662
663     ExternalAPIUtil getExternalAPIUtil() {
664         return new ExternalAPIUtilFactory().create()
665     }
666 }