6fd8080ef0289f65cd0f08fea2755b5ccd63b0bd
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeAllocateAccessNSSI.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2020 Wipro Limited. All rights reserved.
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 static org.apache.commons.lang3.StringUtils.isBlank
24
25 import javax.ws.rs.NotFoundException
26 import javax.ws.rs.core.Response
27
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
30 import org.onap.aai.domain.yang.*
31 import org.onap.aaiclient.client.aai.AAIObjectType
32 import org.onap.aaiclient.client.aai.AAIResourcesClient
33 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
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.beans.nsmf.DeAllocateNssi
40 import org.onap.so.beans.nsmf.EsrInfo
41 import org.onap.so.beans.nsmf.NetworkType
42 import org.onap.so.beans.nsmf.ServiceInfo
43 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
44 import org.onap.so.bpmn.common.scripts.ExceptionUtil
45 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
46 import org.onap.so.bpmn.common.scripts.OofUtils
47 import org.onap.so.bpmn.common.scripts.RequestDBUtil
48 import org.onap.so.bpmn.core.UrnPropertiesReader
49 import org.onap.so.bpmn.core.json.JsonUtils
50 import org.onap.so.client.HttpClient
51 import org.onap.so.client.HttpClientFactory
52 import org.onap.so.client.oof.adapter.beans.payload.OofRequest
53 import org.onap.so.db.request.beans.ResourceOperationStatus
54 import org.slf4j.Logger
55 import org.slf4j.LoggerFactory
56
57 import com.fasterxml.jackson.databind.ObjectMapper
58 import com.google.gson.JsonObject
59 import com.google.gson.Gson
60
61
62 /**
63  * Internal AN NSSMF to handle NSSI Deallocation
64  */
65 class DoDeAllocateAccessNSSI extends AbstractServiceTaskProcessor {
66
67         String Prefix="DoDeAllocateAccessNSSI"
68         ExceptionUtil exceptionUtil = new ExceptionUtil()
69         RequestDBUtil requestDBUtil = new RequestDBUtil()
70         JsonUtils jsonUtil = new JsonUtils()
71         OofUtils oofUtils = new OofUtils()
72         ObjectMapper objectMapper = new ObjectMapper()
73         private NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
74         
75         private static final Logger logger = LoggerFactory.getLogger(DoDeAllocateAccessNSSI.class)
76         private static final String ROLE_SLICE_PROFILE = "slice-profile-instance"
77         private static final String ROLE_NSSI = "nssi"
78
79         private static final String AN_NF = "AN_NF"
80         private static final String TN_FH = "TN_FH"
81         private static final String TN_MH = "TN_MH"
82
83         @Override
84         public void preProcessRequest(DelegateExecution execution) {
85                 logger.debug("${Prefix} - Start preProcessRequest")
86
87                 String sliceParams = execution.getVariable("sliceParams")
88                 def sNssaiList = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(sliceParams, "snssaiList"))
89                 String anSliceProfileId = jsonUtil.getJsonValue(sliceParams, "sliceProfileId")
90                 String nsiId = jsonUtil.getJsonValue(sliceParams, "nsiId")
91                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
92                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
93                 String anNssiId = execution.getVariable("serviceInstanceID")
94
95                 if((sNssaiList.empty) || isBlank(anSliceProfileId) || isBlank(nsiId)) {
96                         String msg = "Input fields cannot be null : Mandatory attributes : [snssaiList, sliceProfileId, nsiId]"
97                         logger.debug(msg)
98                         exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
99                 }
100
101                 if( isBlank(anNssiId) || isBlank(globalSubscriberId) || isBlank(subscriptionServiceType)) {
102                         String msg = "Missing Input fields from main process : [serviceInstanceID, globalSubscriberId, subscriptionServiceType]"
103                         logger.debug(msg)
104                         exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
105                 }
106
107                 execution.setVariable("sNssaiList", sNssaiList)
108                 execution.setVariable("anSliceProfileId", anSliceProfileId)
109                 execution.setVariable("nsiId", nsiId)
110                 execution.setVariable("anNssiId", anNssiId)
111
112                 logger.debug("${Prefix} - Preprocessing completed with sliceProfileId : ${anSliceProfileId} , nsiId : ${nsiId} , nssiId : ${anNssiId}")
113         }
114
115         /**
116          * Method to fetch AN NSSI Constituents and Slice Profile constituents
117          * @param execution
118          */
119         void getRelatedInstances(DelegateExecution execution) {
120                 logger.debug("${Prefix} - Get Related Instances")
121                 String anSliceProfileId = execution.getVariable("anSliceProfileId")
122                 String anNssiId = execution.getVariable("anNssiId")
123
124                 Map<String,ServiceInstance> relatedSPs = new HashMap<>()
125                 execution.setVariable("relatedSPs", getRelatedInstancesByRole(execution, ROLE_SLICE_PROFILE, anSliceProfileId))
126                 execution.setVariable("anNfSliceProfileId", getInstanceIdByWorkloadContext(execution.getVariable("relatedSPs"), AN_NF))
127
128                 Map<String,ServiceInstance> relatedNssis = new HashMap<>()
129                 relatedNssis = getRelatedInstancesByRole(execution, ROLE_NSSI, anNssiId)
130                 if(relatedNssis.size() == 1) {
131                         execution.setVariable("IsRANNfAlonePresent", true)
132                 }
133                 execution.setVariable("relatedNssis", relatedNssis)
134         }
135         
136
137         /**
138          * @param execution
139          */
140         void prepareOOFAnNssiTerminationRequest(DelegateExecution execution) {
141                 logger.debug("Start prepareOOFTerminationRequest")
142         String requestId = execution.getVariable("msoRequestId")
143                 String messageType = "AN_NSSITermination"
144                 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
145                 String serviceInstanceId = execution.getVariable("nsiId")
146                 String anNssiId = execution.getVariable("anNssiId")
147         String oofRequest = oofUtils.buildTerminateNxiRequest(requestId,anNssiId, "NSSI",messageType,serviceInstanceId)
148                 execution.setVariable("oofAnNssiPayload", oofRequest)
149         logger.debug("Finish prepareOOFTerminationRequest")
150
151         }
152         
153         void performOofAnNSSITerminationCall(DelegateExecution execution) {
154                 boolean terminateAnNSSI = callOofAdapter(execution,execution.getVariable("oofAnNssiPayload"))
155                 execution.setVariable("terminateAnNSSI", terminateAnNSSI)
156         }
157         
158         /**
159          * @param execution
160          */
161         void prepareOOFAnNfNssiTerminationRequest(DelegateExecution execution) {
162                 logger.debug("Start prepareOOFAnNfNssiTerminationRequest")
163                 String requestId = execution.getVariable("msoRequestId")
164                 String messageType = "AN_NF_NSSITermination"
165                 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
166                 String serviceInstanceId = execution.getVariable("anNssiId")
167
168                 String anNfNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"),AN_NF)
169                 execution.setVariable("anNfNssiId", anNfNssiId)
170
171                 String oofRequest = oofUtils.buildTerminateNxiRequest(requestId,anNfNssiId, "NSSI",messageType,serviceInstanceId)
172                 execution.setVariable("oofAnNfNssiPayload", oofRequest)
173                 logger.debug("Finish prepareOOFAnNfNssiTerminationRequest")
174
175         }
176
177         void performOofAnNfNSSITerminationCall(DelegateExecution execution) {
178                 boolean terminateAnNfNSSI = callOofAdapter(execution,execution.getVariable("oofAnNfNssiPayload"))
179                 execution.setVariable("terminateAnNfNSSI", terminateAnNfNSSI)
180                 if(!terminateAnNfNSSI) {
181                         execution.setVariable("modifyAction","deallocate")
182                 }
183         }
184         
185         void prepareSdnrRequest(DelegateExecution execution) {
186
187                 String anNfNssiId = execution.getVariable("anNfNssiId")
188                 String sNssai = execution.getVariable("sNssaiList").get(0)
189                 String sliceProfileId = execution.getVariable("anNfSliceProfileId")
190                 String reqId = execution.getVariable("msoRequestId")
191                 String messageType = "SDNRTerminateResponse"
192                 StringBuilder callbackURL = new StringBuilder(UrnPropertiesReader.getVariable("mso.workflow.message.endpoint", execution))
193                 callbackURL.append("/").append(messageType).append("/").append(reqId)
194
195                 JsonObject input = new JsonObject()
196                 input.addProperty("RANNFNSSIId", anNfNssiId)
197                 input.addProperty("callbackURL", callbackURL.toString())
198                 input.addProperty("sNSSAI", sNssai)
199                 input.addProperty("globalSubscriberId", execution.getVariable("globalSubscriberId") as String)
200                 input.addProperty("subscriptionServiceType", execution.getVariable("subscriptionServiceType") as String)
201                 input.addProperty("sliceProfileId",sliceProfileId)
202                 input.add("additionalproperties", new JsonObject())
203
204                 JsonObject Payload = new JsonObject()
205
206                 JsonObject wrapinput = new JsonObject()
207                 wrapinput.addProperty("action", "deallocate")
208
209                 JsonObject CommonHeader = new JsonObject()
210                 CommonHeader.addProperty("timestamp", new Date(System.currentTimeMillis()).format("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", TimeZone.getDefault()))
211                 CommonHeader.addProperty("api-ver", "1.0")
212                 CommonHeader.addProperty("originator-id", "testing")
213                 CommonHeader.addProperty("request-id", reqId)
214                 CommonHeader.addProperty("sub-request-id", "1")
215                 CommonHeader.add("flags", new JsonObject())
216
217                 JsonObject body = new JsonObject()
218
219                 JsonObject sdnrRequest = new JsonObject()
220                 Payload.add("input", input)
221                 wrapinput.addProperty("payload", Payload.toString())
222                 wrapinput.add("common-header", CommonHeader)
223                 body.add("input", wrapinput)
224                 sdnrRequest.add("body", body)
225                 sdnrRequest.addProperty("version", "1.0")
226                 sdnrRequest.addProperty("rpc-name", "terminateRANSliceInstance")
227                 sdnrRequest.addProperty("correlation-id", reqId)
228                 sdnrRequest.addProperty("type", "request")
229
230                 String json = sdnrRequest.toString()
231                 execution.setVariable("sdnrRequest", json)
232                 execution.setVariable("SDNR_messageType", messageType)
233                 execution.setVariable("SDNR_timeout", "PT10M")
234
235         }
236         
237         void processSdnrResponse(DelegateExecution execution) {
238                 logger.debug("${Prefix} processing SdnrResponse")
239                 Map<String, Object> resMap = objectMapper.readValue(execution.getVariable("SDNR_Response"),Map.class)
240                 String status = resMap.get("status")
241                 String reason = resMap.get("reason")
242                 if("success".equalsIgnoreCase(status)) {
243                         execution.setVariable("isAnNfTerminated", true)
244                 }else {
245                         execution.setVariable("isAnNfTerminated", false)
246                         logger.debug("AN NF Termination failed with reason ${reason}")
247                 }
248                 logger.debug("${Prefix} processed SdnrResponse")
249         }
250         
251         /**
252          * @param execution
253          * @param oofRequest - Request payload to be sent to adapter
254          * @return
255          */
256         boolean callOofAdapter(DelegateExecution execution, Object oofRequest) {
257                 logger.debug("Start callOofAdapter")
258                 String requestId = execution.getVariable("msoRequestId")
259                 String oofAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.oof.endpoint", execution)
260                 URL requestUrl = new URL(oofAdapterEndpoint)
261                 OofRequest oofPayload = new OofRequest()
262                 oofPayload.setApiPath("/api/oof/terminate/nxi/v1")
263                 oofPayload.setRequestDetails(oofRequest)
264                 String requestJson = objectMapper.writeValueAsString(oofPayload)
265                 logger.debug("Calling OOF adapter  : ${requestUrl} with payload : ${requestJson}")
266                 HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.EXTERNAL)
267                 Response httpResponse = httpClient.post(requestJson)
268                 int responseCode = httpResponse.getStatus()
269                 logger.debug("OOF sync response code is: " + responseCode)
270                 if(responseCode < 200 || responseCode >= 300){
271                         logger.debug("OOF request failed with reason : " + httpResponse)
272                         exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
273                 }else {
274                         Map<String,Object> response = objectMapper.readValue(httpResponse.getEntity(),Map.class)
275                         boolean terminateResponse =  response.get("terminateResponse")
276                         if(!terminateResponse) {
277                                 logger.debug("Terminate response is false because " + response.get("reason"))
278                         }
279                         return terminateResponse
280                 }
281         }
282         
283         void deallocateAnNfNssi(DelegateExecution execution) {
284                 logger.debug("${Prefix} - call deallocateAnNfNssi ")
285                 String anNfNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), AN_NF)
286                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
287                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
288
289                 AAIResourcesClient client = new AAIResourcesClient()
290                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(anNfNssiId))
291                 if (!client.exists(uri)) {
292                         logger.debug("AN NF Service Instance was not found in aai : ${anNfNssiId}")
293                 }else {
294                         client.delete(uri)
295                 }
296         }
297         
298         /**
299          * Removes relationship between AN NSSI and AN_NF NSSI
300          * @param execution
301          */
302         void dissociateAnNfNssi(DelegateExecution execution) {
303                 logger.debug("${Prefix} - call dissociateAnNfNssi ")
304                 String anNfNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), AN_NF)
305                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
306                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
307
308                 AAIResourcesClient client = new AAIResourcesClient()
309                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(anNfNssiId))
310                 if (!client.exists(uri)) {
311                         logger.debug("AN NF Service Instance was not found in aai : ${anNfNssiId}")
312                 }else {
313                         client.delete(uri)
314                 }
315         }
316         
317         /**
318          * Method to prepare request for AN NSSI modification
319          * Call Modify AN NSSI in case OOF sends Terminate NSSI=False
320          * @param execution
321          */
322         void preparejobForANNSSIModification(DelegateExecution execution) {
323
324                 String modificationJobId = UUID.randomUUID().toString()
325                 execution.setVariable("modificationJobId", modificationJobId)
326
327                 Map<String,Object> sliceParams = objectMapper.readValue(execution.getVariable("sliceParams"), Map.class)
328                 sliceParams.put("modifyAction", "deallocate")
329                 execution.setVariable("modificationsliceParams", objectMapper.writeValueAsString(sliceParams))
330
331                 String serviceId = execution.getVariable("serviceInstanceID")
332                 String nsiId = execution.getVariable("nsiId")
333                 logger.debug("Generated new job for Service Instance serviceId:" + serviceId + " operationId:" + modificationJobId)
334
335                 ResourceOperationStatus initStatus = new ResourceOperationStatus()
336                 initStatus.setServiceId(serviceId)
337                 initStatus.setOperationId(modificationJobId)
338                 initStatus.setResourceTemplateUUID(nsiId)
339                 initStatus.setOperType("Modify-Deallocate")
340                 requestDBUtil.prepareInitResourceOperationStatus(execution, initStatus)
341
342                 logger.debug(Prefix + "prepareInitOperationStatus Exit")
343         }
344
345         void prepareQueryJobStatus(DelegateExecution execution,String jobId,String networkType,String instanceId) {
346
347                 String responseId = "1"
348                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
349                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
350
351                 JsonObject esrInfo = new JsonObject()
352                 esrInfo.addProperty("networkType", networkType)
353                 esrInfo.addProperty("vendor", "ONAP_internal")
354
355                 JsonObject serviceInfo = new JsonObject()
356                 serviceInfo.addProperty("nsiId", execution.getVariable("nsiId"))
357                 serviceInfo.addProperty("nssiId", instanceId)
358                 serviceInfo.addProperty("globalSubscriberId", globalSubscriberId)
359                 serviceInfo.addProperty("subscriptionServiceType", subscriptionServiceType)
360
361                 execution.setVariable("${networkType}_esrInfo", esrInfo.toString())
362                 execution.setVariable("${networkType}_responseId", responseId)
363                 execution.setVariable("${networkType}_serviceInfo", serviceInfo.toString())
364
365         }
366
367         void validateJobStatus(DelegateExecution execution,String responseDescriptor) {
368                 logger.debug("validateJobStatus ${responseDescriptor}")
369                 String status = jsonUtil.getJsonValue(responseDescriptor, "status")
370                 String statusDescription = jsonUtil.getJsonValue(responseDescriptor, "statusDescription")
371                 if("finished".equalsIgnoreCase(status)) {
372                         execution.setVariable("isSuccess", true)
373                 }else {
374                         execution.setVariable("isSuccess", false)
375                 }
376         }
377         
378         void prepareUpdateJobStatus(DelegateExecution execution,String status,String progress,String statusDescription) {
379                 String nssiId = execution.getVariable("anNssiId")
380                 String jobId = execution.getVariable("jobId")
381                 String nsiId = execution.getVariable("nsiId")
382
383                 ResourceOperationStatus roStatus = new ResourceOperationStatus()
384                 roStatus.setServiceId(nsiId)
385                 roStatus.setOperationId(jobId)
386                 //roStatus.setResourceTemplateUUID(nsiId)
387                 roStatus.setResourceInstanceID(nssiId)
388                 roStatus.setOperType("DeAllocate")
389                 roStatus.setProgress(progress)
390                 roStatus.setStatus(status)
391                 roStatus.setStatusDescription(statusDescription)
392                 requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
393         }
394         
395         void terminateTNFHNssi(DelegateExecution execution) {
396                 logger.debug("Start terminateTNFHNssi in ${Prefix}")
397                 String nssmfRequest = buildDeallocateNssiRequest(execution, TN_FH)
398                 String nssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), TN_FH)
399                 execution.setVariable("tnFHNSSIId", nssiId)
400                 String urlString = "/api/rest/provMns/v1/NSS/SliceProfiles/" + nssiId
401                                 String nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlString, nssmfRequest)
402                                 if (nssmfResponse != null) {
403                                         String jobId = jsonUtil.getJsonValue(nssmfResponse, "jobId")
404                                         execution.setVariable("TN_FH_jobId",jobId)
405                                 } else {
406                                         logger.error("received error message from NSSMF : "+ nssmfResponse)
407                                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000,"Received a Bad Sync Response from NSSMF.")
408                                 }
409                                 logger.debug("Exit terminateTNFHNssi in ${Prefix}")
410         }
411         
412         void terminateTNMHNssi(DelegateExecution execution) {
413                 logger.debug("Start terminateTNMHNssi in ${Prefix}")
414                 String nssmfRequest = buildDeallocateNssiRequest(execution, TN_MH)
415                 String nssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), TN_MH)
416                 execution.setVariable("tnMHNSSIId", nssiId)
417                 String urlString = "/api/rest/provMns/v1/NSS/SliceProfiles/" + nssiId
418                                 String nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlString, nssmfRequest)
419                                 if (nssmfResponse != null) {
420                                         String jobId = jsonUtil.getJsonValue(nssmfResponse, "jobId")
421                                         execution.setVariable("TN_MH_jobId",jobId)
422                                 } else {
423                                         logger.error("received error message from NSSMF : "+ nssmfResponse)
424                                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000,"Received a Bad Sync Response from NSSMF.")
425                                 }
426                                 logger.debug("Exit terminateTNMHNssi in ${Prefix}")
427         }
428         
429         void deleteRanNfSliceProfileInAAI(DelegateExecution execution) {
430                 logger.debug("${Prefix} delete Ran NF SliceProfile In AAI")
431                 String spId = execution.getVariable("anNfSliceProfileId")
432                 deleteServiceInstanceInAAI(execution, spId)
433         }
434         
435         void deleteTNSliceProfileInAAI(DelegateExecution execution) {
436                 logger.debug("${Prefix} delete TN FH SliceProfile In AAI")
437                 String fhSP = getInstanceIdByWorkloadContext(execution.getVariable("relatedSPs"), TN_FH)
438                 deleteServiceInstanceInAAI(execution, fhSP)
439                 logger.debug("${Prefix} delete TN MH SliceProfile In AAI")
440                 String mhSP = getInstanceIdByWorkloadContext(execution.getVariable("relatedSPs"), TN_MH)
441                 deleteServiceInstanceInAAI(execution, mhSP)
442         }
443         
444         void deleteANNSSI(DelegateExecution execution) {
445                 logger.debug("${Prefix} delete AN NSSI")
446                 String nssiId = execution.getVariable("anNssiId")
447                 deleteServiceInstanceInAAI(execution, nssiId)
448         }
449         
450         /**
451          * Fetches a collection of service instances with the specific role and maps it based on workload context
452          * (AN-NF,TN-FH,TN-MH)
453          * @param execution
454          * @param role                  - nssi/slice profile instance
455          * @param instanceId    - id to which the related list to be found
456          * @return
457          */
458         private Map<String,ServiceInstance> getRelatedInstancesByRole(DelegateExecution execution,String role,String instanceId) {
459                 logger.debug("${Prefix} - Fetching related ${role} from AAI")
460                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
461                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
462
463                 if( isBlank(role) || isBlank(instanceId)) {
464                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Role and instanceId are mandatory")
465                 }
466
467                 Map<String,ServiceInstance> relatedInstances = new HashMap<>()
468
469                 AAIResourcesClient client = getAAIClient()
470                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(instanceId))
471                 if (!client.exists(uri)) {
472                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai : ${instanceId}")
473                 }
474                 AAIResultWrapper wrapper = client.get(uri, NotFoundException.class)
475                 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
476                 if(si.isPresent()) {
477                 List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
478                 for (Relationship relationship : relationshipList) {
479                         String relatedTo = relationship.getRelatedTo()
480                         if (relatedTo.toLowerCase() == "service-instance") {
481                                 String relatioshipurl = relationship.getRelatedLink()
482                                 String serviceInstanceId =
483                                                 relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1, relatioshipurl.length())
484                                 uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(serviceInstanceId))
485                                 if (!client.exists(uri)) {
486                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
487                                                         "Service Instance was not found in aai: ${serviceInstanceId} related to ${instanceId}")
488                                 }
489                                 AAIResultWrapper wrapper01 = client.get(uri, NotFoundException.class)
490                                 Optional<ServiceInstance> serviceInstance = wrapper01.asBean(ServiceInstance.class)
491                                 if (serviceInstance.isPresent()) {
492                                         ServiceInstance instance = serviceInstance.get()
493                                         if (role.equalsIgnoreCase(instance.getServiceRole())) {
494                                                 relatedInstances.put(instance.getWorkloadContext(),instance)
495                                         }
496                                 }
497                         }
498                 }
499                 }
500                 logger.debug("Found ${relatedInstances.size()} ${role} related to ${instanceId} ")
501                 return relatedInstances
502         }
503         
504         private String getInstanceIdByWorkloadContext(Map<String,ServiceInstance> instances,String workloadContext ) {
505                 String instanceId = instances.get(workloadContext).getServiceInstanceId()
506                 if(instanceId == null) {
507                         throw new BpmnError( 2500, "${workloadContext} NSSI ID is not found.")
508                 }
509                 return instanceId
510         }
511         
512         /**
513          * Method to handle deallocation of RAN NSSI constituents(TN_FH/TN_MH)
514          * @param execution
515          * @param serviceFunction - TN_FH/TN_MH
516          * @return
517          */
518         private String buildDeallocateNssiRequest(DelegateExecution execution,String serviceFunction) {
519                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
520                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
521                 Map<String, ServiceInstance> relatedNssis = execution.getVariable("relatedNssis")
522
523                 String anNssiId = execution.getVariable("anNssiId")
524                 List<String> sNssaiList = execution.getVariable("sNssaiList")
525
526                 Map<String, ServiceInstance> relatedSPs = execution.getVariable("relatedSPs")
527
528                 DeAllocateNssi deallocateNssi = new DeAllocateNssi()
529                 deallocateNssi.setNsiId(execution.getVariable("nsiId"))
530                 ServiceInstance tnNssi = relatedNssis.get(serviceFunction)
531                 String nssiId = tnNssi.getServiceInstanceId()
532
533                 deallocateNssi.setNssiId(nssiId)
534                 deallocateNssi.setScriptName("TN1")
535                 deallocateNssi.setSnssaiList(sNssaiList)
536                 deallocateNssi.setSliceProfileId(relatedSPs.get(serviceFunction).getServiceInstanceId())
537
538                 JsonObject esrInfo = new JsonObject() 
539                 esrInfo.addProperty("networkType", "tn")
540                 esrInfo.addProperty("vendor", "ONAP_internal")
541
542                 ServiceInfo serviceInfo = new ServiceInfo()
543                 serviceInfo.setServiceInvariantUuid(tnNssi.getModelInvariantId())
544                 serviceInfo.setServiceUuid(tnNssi.getModelVersionId())
545                 serviceInfo.setGlobalSubscriberId(globalSubscriberId)
546                 serviceInfo.setSubscriptionServiceType(subscriptionServiceType)
547                 serviceInfo.setNssiId(nssiId)
548                 serviceInfo.setNssiName(tnNssi.getServiceInstanceName())
549
550                 JsonObject json = new JsonObject()
551                 Gson jsonConverter = new Gson()
552                 json.add("deAllocateNssi", jsonConverter.toJsonTree(deallocateNssi))
553                 json.add("esrInfo", esrInfo)
554                 json.add("serviceInfo", jsonConverter.toJsonTree(serviceInfo))
555                 return json.toString()
556                 
557         }
558         
559         private void deleteServiceInstanceInAAI(DelegateExecution execution,String instanceId) {
560                 try {
561                         AAIResourcesClient client = getAAIClient()
562                         AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("subscriptionServiceType")).serviceInstance(instanceId))
563                         client.delete(serviceInstanceUri)
564                         logger.debug("${Prefix} Exited deleteServiceInstance")
565                 }catch(Exception e){
566                         logger.debug("Error occured within deleteServiceInstance method: " + e)
567                 }
568         }
569
570 }