Support Activate,Deactivate and Terminate feature for NSMF based TN slices
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoActivateAccessNSSI.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 import static org.apache.commons.lang3.StringUtils.isBlank
23
24 import javax.ws.rs.NotFoundException
25
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.Relationship
29 import org.onap.aai.domain.yang.ServiceInstance
30 import org.onap.aaiclient.client.aai.AAIObjectType
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.uri.AAIResourceUri
34 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
35 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
37 import org.onap.so.beans.nsmf.ActDeActNssi
38 import org.onap.so.beans.nsmf.EsrInfo
39 import org.onap.so.beans.nsmf.ServiceInfo
40 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
41 import org.onap.so.bpmn.common.scripts.ExceptionUtil
42 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
43 import org.onap.so.bpmn.common.scripts.RequestDBUtil
44 import org.onap.so.bpmn.core.UrnPropertiesReader
45 import org.onap.so.bpmn.core.json.JsonUtils
46 import org.onap.so.db.request.beans.ResourceOperationStatus
47 import org.slf4j.Logger
48 import org.slf4j.LoggerFactory
49
50 import com.fasterxml.jackson.databind.ObjectMapper
51 import com.google.gson.JsonObject
52 import groovy.json.JsonSlurper
53 import com.google.gson.Gson
54
55 /**
56  * Internal AN NSSMF to handle NSSI Activation/Deactivation
57  *
58  */
59 class DoActivateAccessNSSI extends AbstractServiceTaskProcessor {
60         
61         String Prefix="DoActivateAccessNSSI"
62         ExceptionUtil exceptionUtil = new ExceptionUtil()
63         RequestDBUtil requestDBUtil = new RequestDBUtil()
64         JsonUtils jsonUtil = new JsonUtils()
65         ObjectMapper objectMapper = new ObjectMapper()
66         AnNssmfUtils anNssmfUtils = new AnNssmfUtils()
67         private NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
68
69         private static final Logger logger = LoggerFactory.getLogger(DoActivateAccessNSSI.class)
70         private static final String ROLE_SLICE_PROFILE = "slice-profile-instance"
71         private static final String  ROLE_NSSI = "nssi"
72
73         private static final String KEY_SLICE_PROFILE = "SliceProfile"
74         private static final String KEY_NSSI = "NSSI"
75
76         private static final String AN_NF = "AN_NF"
77         private static final String TN_FH = "TN_FH"
78         private static final String TN_MH = "TN_MH"
79
80         private static final String ACTIVATE = "activateInstance"
81         private static final String DEACTIVATE = "deactivateInstance"
82
83         private static final String VENDOR_ONAP = "ONAP_internal"
84
85         enum orchStatusMap {
86                 activateInstance("activated"),
87                 deactivateInstance("deactivated")
88
89                 private String value;
90
91                 private orchStatusMap(String value) {
92                         this.value = value;
93                 }       
94         }
95
96
97         @Override
98         public void preProcessRequest(DelegateExecution execution) {
99                 logger.debug("${Prefix} - Start preProcessRequest")
100
101                 String sliceParams = execution.getVariable("sliceParams")
102                 List<String> sNssaiList = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(sliceParams, "snssaiList"))
103                 String anSliceProfileId = jsonUtil.getJsonValue(sliceParams, "sliceProfileId")
104                 String nsiId = execution.getVariable("nsiId")
105                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
106                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
107                 String anNssiId = execution.getVariable("serviceInstanceID")
108                 String operationType = execution.getVariable("operationType")
109
110                 if((sNssaiList.empty) || isBlank(anSliceProfileId) || isBlank(nsiId)) {
111                         String msg = "Input fields cannot be null : Mandatory attributes : [snssaiList, sliceProfileId, nsiId]"
112                         logger.debug(msg)
113                         exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
114                 }
115
116                 if( isBlank(anNssiId) || isBlank(globalSubscriberId) || isBlank(subscriptionServiceType) || isBlank(operationType)) {
117                         String msg = "Missing Input fields from main process : [serviceInstanceID, globalSubscriberId, subscriptionServiceType, operationType]"
118                         logger.debug(msg)
119                         exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
120                 }
121
122                 execution.setVariable("sNssaiList", sNssaiList)
123                 execution.setVariable("anSliceProfileId", anSliceProfileId)
124                 execution.setVariable("nsiId", nsiId)
125                 execution.setVariable("anNssiId", anNssiId)
126
127                 logger.debug("${Prefix} - Preprocessing completed with sliceProfileId : ${anSliceProfileId} , nsiId : ${nsiId} , nssiId : ${anNssiId}")
128
129         }
130         
131         /**
132          * Method to fetch AN NSSI Constituents and Slice Profile constituents
133          * @param execution
134          */
135         void getRelatedInstances(DelegateExecution execution) {
136                 logger.debug("${Prefix} - Get Related Instances")
137                 String anSliceProfileId = execution.getVariable("anSliceProfileId")
138                 String anNssiId = execution.getVariable("anNssiId")
139
140                 Map<String,ServiceInstance> relatedSPs = new HashMap<>()
141                 execution.setVariable("relatedSPs", getRelatedInstancesByRole(execution, ROLE_SLICE_PROFILE,KEY_SLICE_PROFILE, anSliceProfileId))
142
143                 Map<String,ServiceInstance> relatedNssis = new HashMap<>()
144                 relatedNssis = getRelatedInstancesByRole(execution, ROLE_NSSI,KEY_NSSI, anNssiId)
145                 execution.setVariable("relatedNssis", relatedNssis)
146                 if(relatedNssis.size() == 1) {
147                         execution.setVariable("IsRANNfAlonePresent", true)
148                 }
149                 logger.trace("${Prefix} - Exit Get Related instances")
150         }
151         
152         /**
153          * Method to check Slice profile orchestration status
154          * @param execution
155          */
156         void getSPOrchStatus(DelegateExecution execution) {
157                 logger.debug("${Prefix} - Start getSPOrchStatus")
158                 ServiceInstance sliceProfileInstance = execution.getVariable(KEY_SLICE_PROFILE)
159                 String orchStatus = sliceProfileInstance.getOrchestrationStatus()
160                 String operationType = execution.getVariable("operationType")
161                 if(orchStatusMap.valueOf(operationType).toString().equalsIgnoreCase(orchStatus)) {
162                         execution.setVariable("shouldChangeSPStatus", false)
163                 }else {
164                         execution.setVariable("shouldChangeSPStatus", true)
165                 
166                 }
167                 logger.debug("${Prefix} -  SPOrchStatus  : ${orchStatus}")
168         }
169         
170         /**
171          * Method to check AN NF's  Slice profile instance orchestration status
172          * @param execution
173          */
174         void getAnNfSPOrchStatus(DelegateExecution execution) {
175                 logger.debug("${Prefix} -  getAnNfSPOrchStatus ")
176                 ServiceInstance sliceProfileInstance = getInstanceByWorkloadContext(execution.getVariable("relatedSPs"), AN_NF)
177                 String anNfNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), AN_NF)
178                 execution.setVariable("anNfNssiId", anNfNssiId)
179                 String anNfSPId = sliceProfileInstance.getServiceInstanceId()
180                 execution.setVariable("anNfSPId", anNfSPId)
181
182                 String orchStatus = sliceProfileInstance.getOrchestrationStatus()
183                 String operationType = execution.getVariable("operationType")
184                 if(orchStatusMap.valueOf(operationType).toString().equalsIgnoreCase(orchStatus)) {
185                         execution.setVariable("shouldChangeAN_NF_SPStatus", false)
186                 }else {
187                         execution.setVariable("shouldChangeAN_NF_SPStatus", true)
188                 }
189                 logger.debug("${Prefix} -  getAnNfSPOrchStatus AN_NF SP ID:${anNfSPId}  : ${orchStatus}")
190         }
191
192         void prepareSdnrActivationRequest(DelegateExecution execution) {
193                 logger.debug("${Prefix} - start prepareSdnrActivationRequest")
194                 String operationType = execution.getVariable("operationType")
195                 String action = operationType.equalsIgnoreCase(ACTIVATE) ? "activate":"deactivate"
196
197                 String anNfNssiId = execution.getVariable("anNfNssiId")
198                 List<String> sNssai = execution.getVariable("sNssaiList")
199                 String reqId = execution.getVariable("msoRequestId")
200                 String messageType = "SDNRActivateResponse"
201                 StringBuilder callbackURL = new StringBuilder(UrnPropertiesReader.getVariable("mso.workflow.message.endpoint", execution))
202                 callbackURL.append("/").append(messageType).append("/").append(reqId)
203
204                 JsonObject input = new JsonObject()
205                 String sliceProfileId = execution.getVariable("anNfSPId")
206                 input.addProperty("sliceProfileId",sliceProfileId)
207                 input.addProperty("RANNFNSSIId", anNfNssiId)
208                 input.addProperty("callbackURL", callbackURL.toString())
209                 input.addProperty("sNSSAI", sNssai.toString())
210
211                 JsonObject wrapinput = new JsonObject()
212                 wrapinput.addProperty("action", action)
213
214                 JsonObject CommonHeader = new JsonObject()
215                 CommonHeader.addProperty("timestamp",new Date(System.currentTimeMillis()).format("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", TimeZone.getDefault()))
216                 CommonHeader.addProperty("api-ver", "1.0")
217                 CommonHeader.addProperty("request-id", reqId)
218                 CommonHeader.addProperty("sub-request-id", "1")
219
220                 JsonObject body = new JsonObject()
221                 body.add("input", wrapinput)
222
223                 JsonObject sdnrRequest = new JsonObject()
224                 JsonObject payload = new JsonObject()
225                 payload.add("input", input)
226                 wrapinput.addProperty("payload", payload.toString())
227                 wrapinput.add("common-header", CommonHeader)
228                 body.add("input", wrapinput)
229                 sdnrRequest.add("body", body)
230                 sdnrRequest.addProperty("version", "1.0")
231                 sdnrRequest.addProperty("rpc-name", "activateRANSliceInstance")
232                 sdnrRequest.addProperty("correlation-id", reqId)
233                 sdnrRequest.addProperty("type", "request")
234
235                 String json = sdnrRequest.toString()
236                 execution.setVariable("sdnrRequest", json)
237                 execution.setVariable("SDNR_messageType", messageType)
238                 execution.setVariable("SDNR_timeout", "PT10M")
239
240                 logger.debug("${Prefix} -  Exit prepareSdnrActivationRequest ")
241         }
242
243         void processSdnrResponse(DelegateExecution execution) {
244                 logger.debug("${Prefix} processing SdnrResponse")
245                 Map<String, Object> resMap = objectMapper.readValue(execution.getVariable("SDNR_Response"),Map.class)
246                 String status = resMap.get("status")
247                 String reason = resMap.get("reason")
248                 if("success".equalsIgnoreCase(status)) {
249                         execution.setVariable("isANactivationSuccess", true)
250                 }else {
251                         execution.setVariable("isANactivationSuccess", false)
252                         logger.debug("AN NF Activation/Deactivation failed with reason ${reason}")
253                 }
254                 logger.debug("${Prefix} processed SdnrResponse")
255         }
256         
257         /**
258          * Update AN NF - NSSI and SP Instance status
259          * @param execution
260          */
261         void updateAnNfStatus(DelegateExecution execution) {
262                 logger.debug("${Prefix}Start updateAnNfStatus")
263                 String anNfNssiId = execution.getVariable("anNfNssiId")
264                 String anNfSPId =  execution.getVariable("anNfSPId")
265
266                 updateOrchStatus(execution, anNfSPId)
267                 updateOrchStatus(execution, anNfNssiId)
268                 logger.debug("${Prefix}Exit  updateAnNfStatus")
269         }
270         
271         /**
272          * Method to check AN NF's  Slice profile instance orchestration status
273          * @param execution
274          */
275         void getTnFhSPOrchStatus(DelegateExecution execution) {
276                 logger.debug("${Prefix} start getTnFhSPOrchStatus ")
277                 ServiceInstance sliceProfileInstance = getInstanceByWorkloadContext(execution.getVariable("relatedSPs"), TN_FH)
278                 String tnFhNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), TN_FH)
279                 execution.setVariable("tnFhNssiId", tnFhNssiId)
280                 String tnFhSPId = sliceProfileInstance.getServiceInstanceId()
281                 execution.setVariable("tnFhSPId", tnFhSPId)
282
283                 String orchStatus = sliceProfileInstance.getOrchestrationStatus()
284                 String operationType = execution.getVariable("operationType")
285                 if(orchStatusMap.valueOf(operationType).toString().equalsIgnoreCase(orchStatus)) {
286                         execution.setVariable("shouldChangeTN_FH_SPStatus", false)
287                 }else {
288                         execution.setVariable("shouldChangeTN_FH_SPStatus", true)
289                 }
290
291                 logger.debug("${Prefix} Exit getTnFhSPOrchStatus TN_FH SP ID:${tnFhSPId}  : ${orchStatus}")
292         }
293         
294         void doTnFhNssiActivation(DelegateExecution execution){
295                 logger.debug("Start doTnFhNssiActivation in ${Prefix}")
296                 String nssmfRequest = buildTNActivateNssiRequest(execution, TN_FH)
297                 String operationType = execution.getVariable("operationType")
298                 String urlOpType = operationType.equalsIgnoreCase(ACTIVATE) ? "activation":"deactivation"
299
300                 List<String> sNssaiList =  execution.getVariable("sNssaiList")
301                 String snssai = sNssaiList.get(0) 
302                 String urlString = "/api/rest/provMns/v1/NSS/" + snssai + "/" + urlOpType
303                                 String nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlString, nssmfRequest)
304                                 if (nssmfResponse != null) {
305                                         String jobId = jsonUtil.getJsonValue(nssmfResponse, "jobId")
306                                         execution.setVariable("TN_FH_jobId",jobId)
307                                 } else {
308                                         logger.error("received error message from NSSMF : "+ nssmfResponse)
309                                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000,"Received a Bad Sync Response from NSSMF.")
310                                 }
311                 logger.debug("Exit doTnFhNssiActivation in ${Prefix}")
312         }
313
314         void getTnMhSPOrchStatus(DelegateExecution execution) {
315                 logger.debug("${Prefix} Start getTnMhSPOrchStatus ")
316                 ServiceInstance sliceProfileInstance = getInstanceByWorkloadContext(execution.getVariable("relatedSPs"), TN_MH)
317                 String tnFhNssiId = getInstanceIdByWorkloadContext(execution.getVariable("relatedNssis"), TN_MH)
318                 execution.setVariable("tnMhNssiId", tnFhNssiId)
319                 String tnFhSPId = sliceProfileInstance.getServiceInstanceId()
320                 execution.setVariable("tnMhSPId", tnFhSPId)
321
322                 String orchStatus = sliceProfileInstance.getOrchestrationStatus()
323                 String operationType = execution.getVariable("operationType")
324                 if(orchStatusMap.valueOf(operationType).toString().equalsIgnoreCase(orchStatus)) {
325                         execution.setVariable("shouldChangeTN_MH_SPStatus", false)
326                 }else {
327                         execution.setVariable("shouldChangeTN_MH_SPStatus", true)
328                 }
329                         logger.debug("${Prefix} Exit getTnMhSPOrchStatus TN_MH SP ID:${tnFhSPId}  : ${orchStatus}")
330         }
331         
332         void doTnMhNssiActivation(DelegateExecution execution){
333                 logger.debug("Start doTnMhNssiActivation in ${Prefix}")
334                 String nssmfRequest = buildTNActivateNssiRequest(execution, TN_MH)
335                 String operationType = execution.getVariable("operationType")
336                 String urlOpType = operationType.equalsIgnoreCase(ACTIVATE) ? "activation":"deactivation"
337
338                 List<String> sNssaiList =  execution.getVariable("sNssaiList")
339                 String snssai = sNssaiList.get(0) 
340
341                 String urlString = "/api/rest/provMns/v1/NSS/" + snssai + "/"  + urlOpType
342                                 String nssmfResponse = nssmfAdapterUtils.sendPostRequestNSSMF(execution, urlString, nssmfRequest)
343                                 if (nssmfResponse != null) {
344                                         String jobId = jsonUtil.getJsonValue(nssmfResponse, "jobId")
345                                         execution.setVariable("TN_MH_jobId",jobId)
346                                 } else {
347                                         logger.error("received error message from NSSMF : "+ nssmfResponse)
348                                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000,"Received a Bad Sync Response from NSSMF.")
349                                 }
350                                 logger.debug("Exit doTnMhNssiActivation in ${Prefix}")
351                 
352         }
353         
354         /**
355          * Update TN FH - NSSI and SP Instance status
356          * @param execution
357          */
358         void updateTNFHStatus(DelegateExecution execution) {
359                 logger.debug("${Prefix} Start updateTNFHStatus")
360
361                 String tnFhNssiId = execution.getVariable("tnFhNssiId")
362                 String tnFhSPId =  execution.getVariable("tnFhSPId")
363                 updateOrchStatus(execution, tnFhSPId)
364                 updateOrchStatus(execution, tnFhNssiId)
365
366                 logger.debug("${Prefix} Exit updateTNFHStatus")
367                 
368         }
369         
370         /**
371          * Update TN MH - NSSI and SP Instance status
372          * @param execution
373          */
374         void updateTNMHStatus(DelegateExecution execution) {
375                 logger.debug("${Prefix} Start updateTNMHStatus")
376
377                 String tnMhNssiId = execution.getVariable("tnMhNssiId")
378                 String tnMhSPId =  execution.getVariable("tnMhSPId")
379                 updateOrchStatus(execution, tnMhSPId)
380                 updateOrchStatus(execution, tnMhNssiId)
381
382                 logger.debug("${Prefix} Exit updateTNMHStatus")
383         }
384         
385         /**
386          * Update AN - NSSI and SP Instance status
387          * @param execution
388          */
389         void updateANStatus(DelegateExecution execution) {
390                 logger.debug("${Prefix} Start updateANStatus")
391                 String anNssiId = execution.getVariable("anNssiId")
392                 String anSliceProfileId =  execution.getVariable("anSliceProfileId")
393                 updateOrchStatus(execution, anNssiId)
394                 updateOrchStatus(execution, anSliceProfileId)
395                 logger.debug("${Prefix} Exit updateANStatus")
396         }
397         
398         void prepareQueryJobStatus(DelegateExecution execution,String jobId,String networkType,String instanceId) {
399                 logger.debug("${Prefix} Start prepareQueryJobStatus : ${jobId}")
400                 String responseId = "1"
401                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
402                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
403
404                 JsonObject esrInfo = new JsonObject()
405                 esrInfo.addProperty("networkType", networkType)
406                 esrInfo.addProperty("vendor", VENDOR_ONAP)
407
408                 JsonObject serviceInfo = new JsonObject()
409                 serviceInfo.addProperty("nsiId", execution.getVariable("nsiId"))
410                 serviceInfo.addProperty("nssiId", instanceId)
411                 serviceInfo.addProperty("globalSubscriberId", globalSubscriberId)
412                 serviceInfo.addProperty("subscriptionServiceType", subscriptionServiceType)
413
414                 execution.setVariable("${networkType}_esrInfo", esrInfo.toString())
415                 execution.setVariable("${networkType}_responseId", responseId)
416                 execution.setVariable("${networkType}_serviceInfo", serviceInfo.toString())
417                 
418         }
419         
420         void validateJobStatus(DelegateExecution execution,String responseDescriptor) {
421                 logger.debug("validateJobStatus ${responseDescriptor}")
422                 String jobResponse = execution.getVariable("tn_responseDescriptor")
423                 logger.debug("Job status response "+jobResponse)
424                 String status = jsonUtil.getJsonValue(jobResponse, "status")
425                 String statusDescription = jsonUtil.getJsonValue(jobResponse, "statusDescription")
426                 if("finished".equalsIgnoreCase(status)) {
427                         execution.setVariable("isSuccess", true)
428                 }else {
429                         execution.setVariable("isSuccess", false)
430                 }
431         }
432         
433         
434         private void updateOrchStatus(DelegateExecution execution,String serviceId) {
435                 logger.debug("${Prefix} Start updateOrchStatus : ${serviceId}")
436                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
437                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
438                 String operationType = execution.getVariable("operationType")
439
440                 try {
441                         AAIResourcesClient client = new AAIResourcesClient()
442                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(serviceId))
443                         if (!client.exists(uri)) {
444                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai")
445                         }
446                         AAIResultWrapper wrapper = client.get(uri, NotFoundException.class)
447                         Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
448                         if (si.isPresent()) {
449                                 String orchStatus = si.get().getOrchestrationStatus()
450                                 logger.debug("Orchestration status of instance ${serviceId} is ${orchStatus}")
451                                 if (ACTIVATE.equalsIgnoreCase(operationType) && "deactivated".equalsIgnoreCase(orchStatus)) {
452                                                 si.get().setOrchestrationStatus("activated")
453                                                 client.update(uri, si.get())
454                                 } else if(DEACTIVATE.equalsIgnoreCase(operationType) && "activated".equalsIgnoreCase(orchStatus)){
455                                                 si.get().setOrchestrationStatus("deactivated")
456                                                 client.update(uri, si.get())
457                                 }
458                         }
459                 } catch (Exception e) {
460                         logger.info("Service is already in active state")
461                         String msg = "Service is already in active state, " + e.getMessage()
462                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
463                 }
464                 logger.debug("${Prefix} Exit updateOrchStatus : ${serviceId}")
465         }
466         
467         void prepareUpdateJobStatus(DelegateExecution execution,String status,String progress,String statusDescription) {
468                 logger.debug("${Prefix} Start prepareUpdateJobStatus : ${statusDescription}")
469                 String nssiId = execution.getVariable("anNssiId")
470                 String jobId = execution.getVariable("jobId")
471                 String nsiId = execution.getVariable("nsiId")
472                 //String modelUuid = execution.getVariable("modelUuid")
473                 String modelUuid = anNssmfUtils.getModelUuid(execution, nssiId)
474                 String operationType = execution.getVariable("operationType")
475
476                 ResourceOperationStatus roStatus = new ResourceOperationStatus()
477                 roStatus.setServiceId(nsiId)
478                 roStatus.setOperationId(jobId)
479                 roStatus.setResourceTemplateUUID(modelUuid)
480                 roStatus.setResourceInstanceID(nssiId)
481                 roStatus.setOperType(operationType)
482                 roStatus.setProgress(progress)
483                 roStatus.setStatus(status)
484                 roStatus.setStatusDescription(statusDescription)
485                 requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
486                 logger.debug("${Prefix} Exit prepareUpdateJobStatus : ${statusDescription}")
487         }
488         
489         
490         
491         /**
492          * Fetches a collection of service instances with the specific role and maps it based on workload context
493          * (AN-NF,TN-FH,TN-MH)
494          * @param execution
495          * @param role                  - nssi/slice profile instance
496          * @param key                   - NSSI/Sliceprofile corresponding to instanceId
497          * @param instanceId    - id to which the related list to be found
498          * @return
499          */
500         private Map<String,ServiceInstance> getRelatedInstancesByRole(DelegateExecution execution,String role,String key, String instanceId) {
501                 logger.debug("${Prefix} - Fetching related ${role} from AAI")
502                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
503                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
504                 
505                 if( isBlank(role) || isBlank(instanceId)) {
506                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Role and instanceId are mandatory")
507                 }
508
509                 Map<String,ServiceInstance> relatedInstances = new HashMap<>()
510                 
511                 AAIResourcesClient client = getAAIClient()
512                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(instanceId))
513                 if (!client.exists(uri)) {
514                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Service Instance was not found in aai : ${instanceId}")
515                 }
516                 AAIResultWrapper wrapper = client.get(uri, NotFoundException.class)
517                 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
518                 if(si.isPresent()) {
519                 execution.setVariable(key, si.get())
520                 List<Relationship> relationshipList = si.get().getRelationshipList().getRelationship()
521                 for (Relationship relationship : relationshipList) {
522                         String relatedTo = relationship.getRelatedTo()
523                         if (relatedTo.toLowerCase() == "service-instance") {
524                                 String relatioshipurl = relationship.getRelatedLink()
525                                 String serviceInstanceId =
526                                                 relatioshipurl.substring(relatioshipurl.lastIndexOf("/") + 1, relatioshipurl.length())
527                                 uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(serviceInstanceId))
528                                 if (!client.exists(uri)) {
529                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500,
530                                                         "Service Instance was not found in aai: ${serviceInstanceId} related to ${instanceId}")
531                                 }
532                                 AAIResultWrapper wrapper01 = client.get(uri, NotFoundException.class)
533                                 Optional<ServiceInstance> serviceInstance = wrapper01.asBean(ServiceInstance.class)
534                                 if (serviceInstance.isPresent()) {
535                                         ServiceInstance instance = serviceInstance.get()
536                                         if (role.equalsIgnoreCase(instance.getServiceRole())) {
537                                                 relatedInstances.put(instance.getWorkloadContext(),instance)
538                                         }
539                                 }
540                         }
541                 }
542                 }
543                 logger.debug("Found ${relatedInstances.size()} ${role} related to ${instanceId} ")
544                 return relatedInstances
545         }
546         
547         private ServiceInstance getInstanceByWorkloadContext(Map<String,ServiceInstance> instances,String workloadContext ) {
548                 ServiceInstance instance = instances.get(workloadContext)
549                 if(instance == null) {
550                         throw new BpmnError( 2500, "${workloadContext} Instance ID is not found.")
551                 }
552                 return instance
553         }
554         
555         private String getInstanceIdByWorkloadContext(Map<String,ServiceInstance> instances,String workloadContext ) {
556                 String instanceId = instances.get(workloadContext).getServiceInstanceId()
557                 if(instanceId == null) {
558                         throw new BpmnError( 2500, "${workloadContext} instance ID is not found.")
559                 }
560                 return instanceId
561         }
562         
563         
564         /**
565          * Method to handle deallocation of RAN NSSI constituents(TN_FH/TN_MH)
566          * @param execution
567          * @param serviceFunction - TN_FH/TN_MH
568          * @return
569          */
570         private String buildTNActivateNssiRequest(DelegateExecution execution,String serviceFunction) {
571                 logger.debug("${Prefix} Exit buildTNActivateNssiRequest : ${serviceFunction}")
572                 String globalSubscriberId = execution.getVariable("globalSubscriberId")
573                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
574                 Map<String, ServiceInstance> relatedNssis = execution.getVariable("relatedNssis")
575
576                 String nsiId = execution.getVariable("nsiId")
577                 List<String> sNssaiList =  execution.getVariable("sNssaiList")
578
579                 ServiceInstance tnNssi = relatedNssis.get(serviceFunction)
580                 String nssiId = tnNssi.getServiceInstanceId()
581
582                 Map<String, ServiceInstance> relatedSPs = execution.getVariable("relatedSPs")
583
584                 ActDeActNssi actDeactNssi = new ActDeActNssi()
585                 actDeactNssi.setNssiId(nssiId)
586                 actDeactNssi.setNsiId(nsiId)
587                 actDeactNssi.setSliceProfileId(relatedSPs.get(serviceFunction).getServiceInstanceId())
588                 actDeactNssi.setSnssaiList(sNssaiList)
589
590                 JsonObject esrInfo = new JsonObject()
591                 esrInfo.addProperty("networkType", "tn")
592                 esrInfo.addProperty("vendor", VENDOR_ONAP)
593
594                 ServiceInfo serviceInfo = new ServiceInfo()
595                 serviceInfo.setServiceInvariantUuid(tnNssi.getModelInvariantId())
596                 serviceInfo.setServiceUuid(tnNssi.getModelVersionId())
597                 serviceInfo.setGlobalSubscriberId(globalSubscriberId)
598                 serviceInfo.setSubscriptionServiceType(subscriptionServiceType)
599                 serviceInfo.setNssiId(nssiId)
600
601                 JsonObject json = new JsonObject()
602                 Gson jsonConverter = new Gson()
603                 json.add("actDeActNssi", jsonConverter.toJsonTree(actDeactNssi))
604                 json.add("esrInfo", esrInfo)
605                 json.add("serviceInfo", jsonConverter.toJsonTree(serviceInfo))
606                 return json.toString()
607                 
608         }
609         
610 }