Fix bugs found in TN Slicing integration involving OOF
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / TnAllocateNssi.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2020 Huawei Technologies Co., Ltd. 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 com.fasterxml.jackson.core.type.TypeReference
24 import com.fasterxml.jackson.databind.ObjectMapper
25 import org.json.JSONArray
26 import com.google.gson.JsonArray
27 import com.google.gson.GsonBuilder
28 import com.google.gson.JsonObject
29 import com.google.gson.JsonParser
30 import groovy.json.JsonSlurper
31 import org.onap.so.bpmn.common.scripts.OofUtils
32 import com.google.gson.Gson
33 import org.camunda.bpm.engine.delegate.BpmnError
34 import org.camunda.bpm.engine.delegate.DelegateExecution
35 import org.onap.aai.domain.yang.ServiceInstance
36 import org.onap.aaiclient.client.aai.AAIResourcesClient
37 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
38 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
39 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
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.RequestDBUtil
43 import org.onap.so.bpmn.core.UrnPropertiesReader
44 import org.onap.so.bpmn.core.domain.ServiceDecomposition
45 import org.onap.so.bpmn.core.domain.ServiceProxy
46 import org.onap.so.bpmn.core.json.JsonUtils
47 import org.onap.so.db.request.beans.ResourceOperationStatus
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
50 import org.springframework.web.util.UriUtils
51
52 import static org.apache.commons.lang3.StringUtils.isBlank
53
54 class TnAllocateNssi extends AbstractServiceTaskProcessor {
55     String Prefix = "TNALLOC_"
56
57     ExceptionUtil exceptionUtil = new ExceptionUtil()
58     JsonUtils jsonUtil = new JsonUtils()
59     RequestDBUtil requestDBUtil = new RequestDBUtil()
60     JsonSlurper jsonSlurper = new JsonSlurper()
61     ObjectMapper objectMapper = new ObjectMapper()
62     OofUtils oofUtils = new OofUtils()
63     TnNssmfUtils tnNssmfUtils = new TnNssmfUtils()
64     private static final Logger logger = LoggerFactory.getLogger(TnAllocateNssi.class)
65
66     void preProcessRequest(DelegateExecution execution) {
67         logger.debug("Start preProcessRequest")
68         execution.setVariable("prefix", Prefix)
69         String msg = ""
70
71         try {
72             execution.setVariable("startTime", System.currentTimeMillis())
73
74             msg = tnNssmfUtils.getExecutionInputParams(execution)
75             logger.debug("Allocate TN NSSI input parameters: " + msg)
76
77             tnNssmfUtils.setSdncCallbackUrl(execution, true)
78             logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
79
80             String additionalPropJsonStr = execution.getVariable("sliceParams")
81
82             String tnNssiId = jsonUtil.getJsonValue(additionalPropJsonStr, "serviceInstanceID") //for debug
83             if (isBlank(tnNssiId)) {
84                 tnNssiId = UUID.randomUUID().toString()
85             }
86
87             String operationId = UUID.randomUUID().toString()
88             execution.setVariable("operationId", operationId)
89
90             logger.debug("Generate new TN NSSI ID:" + tnNssiId)
91             tnNssiId = UriUtils.encode(tnNssiId, "UTF-8")
92             execution.setVariable("sliceServiceInstanceId", tnNssiId)
93
94             String sliceServiceInstanceName = execution.getVariable("servicename")
95             execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
96
97             String sst = execution.getVariable("sst")
98             execution.setVariable("sst", sst)
99
100             //additional properties
101             String sliceProfile = jsonUtil.getJsonValue(additionalPropJsonStr, "sliceProfile")
102             if (isBlank(sliceProfile)) {
103                 msg = "Input sliceProfile is null"
104                 logger.debug(msg)
105                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
106             }
107             else {
108                 execution.setVariable("sliceProfile", sliceProfile)
109             }
110
111             String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
112             if (isBlank(transportSliceNetworks)) {
113                 msg = "Input transportSliceNetworks is null"
114                 logger.debug(msg)
115                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
116             }
117             else {
118                 execution.setVariable("transportSliceNetworks", transportSliceNetworks)
119             }
120             logger.debug("transportSliceNetworks: " + transportSliceNetworks)
121
122             String nsiInfoStr = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
123             if (isBlank(nsiInfoStr)) {
124                 msg = "Input nsiInfo is null"
125                 logger.debug(msg)
126                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
127             }
128             else {
129                 execution.setVariable("nsiInfo", nsiInfoStr)
130             }
131
132             if (isBlank(tnNssmfUtils.setExecVarFromJsonIfExists(execution, additionalPropJsonStr,
133                     "enableSdnc", "enableSdnc"))) {
134                 tnNssmfUtils.setEnableSdncConfig(execution)
135             }
136
137             if (isBlank(additionalPropJsonStr) ||
138                     isBlank(tnNssmfUtils.setExecVarFromJsonIfExists(execution,
139                             additionalPropJsonStr,
140                             "enableOof", "enableOof"))) {
141                 tnNssmfUtils.setEnableOofConfig(execution)
142             }
143
144         } catch (BpmnError e) {
145             throw e
146         } catch (Exception ex) {
147             msg = "Exception in preProcessRequest " + ex.getMessage()
148             logger.debug(msg)
149             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
150         }
151         logger.debug("Finish preProcessRequest")
152     }
153
154
155     void prepareDecomposeService(DelegateExecution execution) {
156         logger.debug("Start prepareDecomposeService")
157         String msg = ""
158         String modelUuid = execution.getVariable("modelUuid")
159         if (isBlank(modelUuid)) {
160             msg = "Input modelUuid is null"
161             logger.debug(msg)
162             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
163         }
164
165         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
166         if (isBlank(modelInvariantUuid)) {
167             msg = "Input modelInvariantUuid is null"
168             logger.debug(msg)
169             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
170         }
171
172         String serviceModelInfo = """{
173             "modelInvariantUuid":"${modelInvariantUuid}",
174             "modelUuid":"${modelUuid}",
175             "modelVersion":""
176              }"""
177         execution.setVariable("serviceModelInfo", serviceModelInfo)
178
179         logger.debug("Finish prepareDecomposeService")
180     }
181
182     void processDecomposition(DelegateExecution execution) {
183         logger.debug("Start processDecomposition")
184
185         ServiceDecomposition tnNsstServiceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
186         logger.debug("tnNsstServiceDecomposition : " + tnNsstServiceDecomposition.toString())
187         //TN NSST decomposition
188         String tnModelVersion = tnNsstServiceDecomposition.getModelInfo().getModelVersion()
189         String tnModelName = tnNsstServiceDecomposition.getModelInfo().getModelName()
190
191         List<ServiceProxy> serviceProxyList = tnNsstServiceDecomposition.getServiceProxy()
192         List<String> nsstInfoList = new ArrayList<>()
193         for (ServiceProxy serviceProxy : serviceProxyList) {
194             String nsstModelUuid = serviceProxy.getModelInfo().getModelUuid()
195             String nsstModelInvariantUuid = serviceProxy.getModelInfo().getModelInvariantUuid()
196             String name = serviceProxy.getModelInfo().getModelName()
197             String nsstServiceModelInfo = """{
198             "UUID":"${nsstModelUuid}",
199             "invariantUUID":"${nsstModelInvariantUuid}",
200             "name":"${name}"
201              }"""
202             nsstInfoList.add(nsstServiceModelInfo)
203         }
204         int currentIndex = 0
205         int maxIndex = nsstInfoList.size()
206         if (maxIndex < 1) {
207             String msg = "Exception in TN NSST processDecomposition. There is no NSST associated with TN NSST "
208             logger.info(msg)
209             //exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
210         }
211         else {
212             execution.setVariable("tnNsstInfoList", nsstInfoList)
213             execution.setVariable("tnModelVersion", tnModelVersion)
214             execution.setVariable("tnModelName", tnModelName)
215             execution.setVariable("currentIndex", currentIndex)
216             execution.setVariable("maxIndex", maxIndex)
217         }
218
219         execution.setVariable("tnNfSliceProfile", execution.getVariable("sliceProfile"))
220         execution.setVariable("tnModelName", tnModelName)
221         logger.debug("End processDecomposition")
222     }
223
224     void prepareOofSelection(DelegateExecution execution) {
225         logger.debug("Start prepareOofSelection")
226
227         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
228         logger.debug("get NSSI option OOF Url: " + urlString)
229         //build oof request body
230
231         String requestId = execution.getVariable("msoRequestId")
232         String messageType = "NSSISelectionResponse"
233         Map<String, Object> profileInfo = (Map<String, Object>) objectMapper.readValue(execution.getVariable("tnNfSliceProfile"), Map.class)
234         String modelUuid = execution.getVariable("modelUuid")
235         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
236         String modelName = execution.getVariable("tnModelName")
237         String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
238
239         execution.setVariable("nssiSelection_Url", "/api/oof/selection/nssi/v1")
240         execution.setVariable("nssiSelection_messageType", messageType)
241         execution.setVariable("nssiSelection_correlator", requestId)
242         execution.setVariable("nssiSelection_timeout", timeout)
243         String oofRequest = oofUtils.buildSelectNSSIRequest(requestId, messageType, modelUuid, modelInvariantUuid, modelName, profileInfo)
244         execution.setVariable("nssiSelection_oofRequest", oofRequest)
245
246         logger.debug("Finish prepareOofSelection")
247     }
248
249     void processOofSelection(DelegateExecution execution) {
250         logger.debug(Prefix + "processOofSelection method start")
251         String oofResponse = execution.getVariable("nssiSelection_asyncCallbackResponse")
252         String requestStatus = jsonUtil.getJsonValue(oofResponse, "requestStatus")
253         if (requestStatus.equals("completed")) {
254             String solutions = jsonUtil.getJsonValue(oofResponse, "solutions")
255             JsonParser parser = new JsonParser()
256             JsonArray solution = parser.parse(solutions) as JsonArray
257             if (solution.size() >= 1) {
258                 JsonObject sol = solution.get(0) as JsonObject
259                 String tnNfNssiId = sol.get("NSSIId").getAsString()
260                 String invariantUuid = sol.get("invariantUUID").getAsString()
261                 String uuid = sol.get("UUID").getAsString()
262                 String nssiName = sol.get("NSSIName").getAsString()
263                 execution.setVariable("TnServiceInstanceId", tnNfNssiId)
264                 execution.setVariable("TNNFInvariantUUID", invariantUuid)
265                 execution.setVariable("TNNFUUID", uuid)
266                 execution.setVariable("servicename", nssiName)
267                 logger.debug("TnServiceInstanceId from OOF " + tnNfNssiId)
268                 execution.setVariable("isOofTnNssiSelected", true)
269             }
270             else {
271                 logger.debug("No solutions returned from OOF .. Create new TN NF NSSI")
272                 execution.setVariable("isOofTnNssiSelected", false)
273             }
274         }
275         else {
276             String statusMessage = jsonUtil.getJsonValue(oofResponse, "statusMessage")
277             logger.error("received failed status from oof " + statusMessage)
278             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a failed Async Response from OOF : " + statusMessage)
279         }
280
281         logger.debug(Prefix + "processOofSelection method finished")
282     }
283
284     void prepareModifyTnNssiInputs(DelegateExecution execution) {
285         logger.debug(Prefix + "prepareModifyTnNssiInputs method start")
286         String additionalPropJsonStr = execution.getVariable("sliceParams")
287         String sliceProfile = execution.getVariable("sliceProfile")
288         String snssaiList = jsonUtil.getJsonValue(sliceProfile, "snssaiList")
289         String sliceProfileId = jsonUtil.getJsonValue(sliceProfile, "sliceProfileId")
290         String nsiInfo = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
291         String scriptName = jsonUtil.getJsonValue(additionalPropJsonStr, "scriptName")
292         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
293         String modelUuid = execution.getVariable("modelUuid")
294         String serviceInstanceID = execution.getVariable("TnServiceInstanceId")
295         String servicename = execution.getVariable("servicename")
296         String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
297
298         JsonObject modifySliceParams = new JsonObject()
299         modifySliceParams.addProperty("nsiInfo", nsiInfo)
300         modifySliceParams.addProperty("serviceInstanceID", serviceInstanceID)
301         modifySliceParams.addProperty("servicename", servicename)
302         modifySliceParams.addProperty("sliceProfile", sliceProfile)
303         modifySliceParams.addProperty("sliceProfileId", sliceProfileId)
304         modifySliceParams.addProperty("modelInvariantUuid", modelInvariantUuid)
305         modifySliceParams.addProperty("modelUuid", modelUuid)
306         modifySliceParams.addProperty("scriptName", scriptName)
307         modifySliceParams.addProperty("snssaiList", snssaiList)
308         modifySliceParams.addProperty("transportSliceNetworks", transportSliceNetworks)
309
310         execution.setVariable("modifySliceParams", modifySliceParams.toString())
311
312         logger.debug(Prefix + "prepareModifyTnNssiInputs method finished")
313     }
314
315     def createModifyNssiQueryJobStatus = { DelegateExecution execution ->
316         logger.debug(Prefix + "createModifyNssiQueryJobStatus method start")
317         JsonObject esrInfo = new JsonObject()
318         esrInfo.addProperty("networkType", "tn")
319         esrInfo.addProperty("vendor", "ONAP_internal")
320
321         execution.setVariable("esrInfo", esrInfo.toString())
322
323         JsonObject serviceInfo = new JsonObject()
324         serviceInfo.addProperty("nssiId", execution.getVariable("TnServiceInstanceId") as String)
325         serviceInfo.addProperty("nsiId", execution.getVariable("nsiId") as String)
326         serviceInfo.addProperty("nssiName", execution.getVariable("servicename") as String)
327         serviceInfo.addProperty("sST", execution.getVariable("sst") as String)
328         serviceInfo.addProperty("PLMNIdList", objectMapper.writeValueAsString(execution.getVariable("pLMNIdList")))
329         serviceInfo.addProperty("globalSubscriberId", execution.getVariable("globalSubscriberId") as String)
330         serviceInfo.addProperty("subscriptionServiceType", execution.getVariable("subscriptionServiceType") as String)
331         serviceInfo.addProperty("serviceInvariantUuid", execution.getVariable("modelInvariantUuid") as String)
332         serviceInfo.addProperty("serviceUuid", execution.getVariable("modelUuid") as String)
333         execution.setVariable("serviceInfo", serviceInfo.toString())
334         execution.setVariable("responseId", "")
335     }
336
337     def processModifyJobStatusRsp = { DelegateExecution execution ->
338         logger.debug(Prefix + "processJobStatusRsp method start")
339         String jobResponse = execution.getVariable("jobResponse")
340         logger.debug("Job status response " + jobResponse)
341         String status = jsonUtil.getJsonValue(jobResponse, "status")
342         String nssi = jsonUtil.getJsonValue(jobResponse, "nssiId")
343         if (status.equalsIgnoreCase("finished")) {
344             logger.debug("Job successfully completed ... proceeding with flow for nssi : " + nssi)
345         }
346         else {
347             String statusDescription = jsonUtil.getJsonValue(jobResponse, "statusDescription")
348             logger.error("received failed status from job status query for nssi : " + nssi + " with status description : " + statusDescription)
349             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "received failed status from job status query for nssi : " + nssi + " with status description : " + statusDescription)
350         }
351     }
352
353     void updateAAIOrchStatus(DelegateExecution execution) {
354         logger.debug("Start updateAAIOrchStatus")
355         String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
356         String orchStatus = execution.getVariable("orchestrationStatus")
357
358         try {
359             ServiceInstance si = new ServiceInstance()
360             si.setOrchestrationStatus(orchStatus)
361             AAIResourcesClient client = new AAIResourcesClient()
362             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(sliceServiceInstanceId))
363             client.update(uri, si)
364         } catch (BpmnError e) {
365             throw e
366         } catch (Exception ex) {
367             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
368             logger.info(msg)
369             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
370         }
371
372         logger.debug("Finish updateAAIOrchStatus")
373     }
374
375
376     void prepareUpdateJobStatus(DelegateExecution execution,
377                                 String status,
378                                 String progress,
379                                 String statusDescription) {
380         String modelUuid = execution.getVariable("modelUuid")
381         String ssInstanceId = execution.getVariable("sliceServiceInstanceId")
382         String jobId = execution.getVariable("jobId")
383         String nsiId = execution.getVariable("nsiId")
384
385         ResourceOperationStatus roStatus = new ResourceOperationStatus()
386         roStatus.setServiceId(nsiId)
387         roStatus.setOperationId(jobId)
388         roStatus.setResourceTemplateUUID(modelUuid)
389         roStatus.setResourceInstanceID(ssInstanceId)
390         roStatus.setOperType("ALLOCATE")
391         roStatus.setProgress(progress)
392         roStatus.setStatus(status)
393         roStatus.setStatusDescription(statusDescription)
394         requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)
395     }
396
397 }
398