Merge "Changed the object mapper to ignore unknown fields"
[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.databind.ObjectMapper
24 import com.google.gson.JsonArray
25 import com.google.gson.JsonObject
26 import groovy.json.JsonSlurper
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
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.uri.AAIResourceUri
33 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
34 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
35 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
36 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
37 import org.onap.so.bpmn.common.scripts.ExceptionUtil
38 import org.onap.so.bpmn.common.scripts.RequestDBUtil
39 import org.onap.so.bpmn.core.UrnPropertiesReader
40 import org.onap.so.bpmn.core.domain.ServiceDecomposition
41 import org.onap.so.bpmn.core.domain.ServiceProxy
42 import org.onap.so.bpmn.core.json.JsonUtils
43 import org.onap.so.db.request.beans.ResourceOperationStatus
44 import org.slf4j.Logger
45 import org.slf4j.LoggerFactory
46 import org.springframework.web.util.UriUtils
47
48 import static org.apache.commons.lang3.StringUtils.isBlank
49
50 class TnAllocateNssi extends AbstractServiceTaskProcessor {
51     String Prefix = "TNALLOC_"
52
53     ExceptionUtil exceptionUtil = new ExceptionUtil()
54     JsonUtils jsonUtil = new JsonUtils()
55     RequestDBUtil requestDBUtil = new RequestDBUtil()
56     JsonSlurper jsonSlurper = new JsonSlurper()
57     ObjectMapper objectMapper = new ObjectMapper()
58     TnNssmfUtils tnNssmfUtils = new TnNssmfUtils()
59     private static final Logger logger = LoggerFactory.getLogger(TnAllocateNssi.class)
60
61     void preProcessRequest(DelegateExecution execution) {
62         logger.debug("Start preProcessRequest")
63         execution.setVariable("prefix", Prefix)
64         String msg = ""
65
66         try {
67             execution.setVariable("startTime", System.currentTimeMillis())
68
69             msg = tnNssmfUtils.getExecutionInputParams(execution)
70             logger.debug("Allocate TN NSSI input parameters: " + msg)
71
72             tnNssmfUtils.setSdncCallbackUrl(execution, true)
73             logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
74
75             String additionalPropJsonStr = execution.getVariable("sliceParams")
76
77             String tnNssiId = execution.getVariable("serviceInstanceID")
78             if (isBlank(tnNssiId)) {
79                 tnNssiId = UUID.randomUUID().toString()
80             }
81
82             String operationId = UUID.randomUUID().toString()
83             execution.setVariable("operationId", operationId)
84
85             logger.debug("Generate new TN NSSI ID:" + tnNssiId)
86             tnNssiId = UriUtils.encode(tnNssiId, "UTF-8")
87             execution.setVariable("sliceServiceInstanceId", tnNssiId)
88
89             String sliceServiceInstanceName = execution.getVariable("servicename")
90             execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
91
92             //additional properties
93             String sliceProfile = jsonUtil.getJsonValue(additionalPropJsonStr, "sliceProfile")
94             if (isBlank(sliceProfile)) {
95                 msg = "Input sliceProfile is null"
96                 logger.debug(msg)
97                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
98             } else {
99                 execution.setVariable("sliceProfile", sliceProfile)
100             }
101
102             String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
103             if (isBlank(transportSliceNetworks)) {
104                 msg = "Input transportSliceNetworks is null"
105                 logger.debug(msg)
106                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
107             } else {
108                 execution.setVariable("transportSliceNetworks", transportSliceNetworks)
109             }
110             logger.debug("transportSliceNetworks: " + transportSliceNetworks)
111
112             String nsiInfoStr = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
113             if (isBlank(nsiInfoStr)) {
114                 msg = "Input nsiInfo is null"
115                 logger.debug(msg)
116                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
117             } else {
118                 execution.setVariable("nsiInfo", nsiInfoStr)
119             }
120
121             //nsiId is passed in from caller bpmn
122             //String nsiIdStr = jsonUtil.getJsonValue(nsiInfo, "nsiId")
123             //execution.setVariable("nsiId", nsiIdStr)
124
125         } catch (BpmnError e) {
126             throw e
127         } catch (Exception ex) {
128             msg = "Exception in preProcessRequest " + ex.getMessage()
129             logger.debug(msg)
130             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
131         }
132         logger.debug("Finish preProcessRequest")
133     }
134
135
136     void prepareDecomposeService(DelegateExecution execution) {
137         logger.debug("Start prepareDecomposeService")
138         String msg = ""
139         String modelUuid = execution.getVariable("modelUuid")
140         if (isBlank(modelUuid)) {
141             msg = "Input modelUuid is null"
142             logger.debug(msg)
143             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
144         }
145
146         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
147         if (isBlank(modelInvariantUuid)) {
148             msg = "Input modelInvariantUuid is null"
149             logger.debug(msg)
150             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
151         }
152
153         String serviceModelInfo = """{
154             "modelInvariantUuid":"${modelInvariantUuid}",
155             "modelUuid":"${modelUuid}",
156             "modelVersion":""
157              }"""
158         execution.setVariable("ssServiceModelInfo", serviceModelInfo)
159
160         logger.debug("Finish prepareDecomposeService")
161     }
162
163     void processDecomposition(DelegateExecution execution) {
164         logger.debug("Start processDecomposition")
165
166         ServiceDecomposition tnNsstServiceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
167         logger.debug("tnNsstServiceDecomposition : " + tnNsstServiceDecomposition.toString())
168         //TN NSST decomposition
169         String tnModelVersion = tnNsstServiceDecomposition.getModelInfo().getModelVersion()
170         String tnModelName = tnNsstServiceDecomposition.getModelInfo().getModelName()
171         List<ServiceProxy> serviceProxyList = tnNsstServiceDecomposition.getServiceProxy()
172         List<String> nsstInfoList = new ArrayList<>()
173         for (ServiceProxy serviceProxy : serviceProxyList) {
174             String nsstModelUuid = serviceProxy.getModelInfo().getModelUuid()
175             String nsstModelInvariantUuid = serviceProxy.getModelInfo().getModelInvariantUuid()
176             String name = serviceProxy.getModelInfo().getModelName()
177             String nsstServiceModelInfo = """{
178             "UUID":"${nsstModelUuid}",
179             "invariantUUID":"${nsstModelInvariantUuid}",
180             "name":"${name}"
181              }"""
182             nsstInfoList.add(nsstServiceModelInfo)
183         }
184         int currentIndex = 0
185         int maxIndex = nsstInfoList.size()
186         if (maxIndex < 1) {
187             String msg = "Exception in TN NSST processDecomposition. There is no NSST associated with TN NSST "
188             logger.info(msg)
189             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
190         }
191         execution.setVariable("tnNsstInfoList", nsstInfoList)
192         execution.setVariable("tnModelVersion", tnModelVersion)
193         execution.setVariable("tnModelName", tnModelName)
194         execution.setVariable("currentIndex", currentIndex)
195         execution.setVariable("maxIndex", maxIndex)
196
197         logger.debug("End processDecomposition")
198     }
199
200     void prepareOofSelection(DelegateExecution execution) {
201         logger.debug("Start prepareOofSelection")
202
203         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
204         logger.debug("get NSSI option OOF Url: " + urlString)
205         //build oof request body
206         String requestId = execution.getVariable("msoRequestId")
207         String messageType = "NSISelectionResponse"
208         Map<String, Object> profileInfo = objectMapper.readValue(execution.getVariable("sliceProfile"), Map.class)
209         String modelUuid = execution.getVariable("modelUuid")
210         String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
211         String modelName = execution.getVariable("tnModelName")
212         String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
213         List<String> nsstInfoList = objectMapper.readValue(execution.getVariable("nsstInfoList"), List.class)
214         JsonArray capabilitiesList = new JsonArray()
215
216         execution.setVariable("nssiSelection_Url", "/api/oof/selection/nsi/v1")
217         execution.setVariable("nssiSelection_messageType", messageType)
218         execution.setVariable("nssiSelection_correlator", requestId)
219         execution.setVariable("nssiSelection_timeout", timeout)
220         String oofRequest = buildSelectTnNssiRequest(requestId, messageType, modelUuid, modelInvariantUuid,
221                 modelName, profileInfo, nsstInfoList, capabilitiesList, false)
222         execution.setVariable("nssiSelection_oofRequest", oofRequest)
223
224         logger.debug("Finish prepareOofSelection")
225     }
226
227     String buildSelectTnNssiRequest(String requestId, String messageType, String UUID, String invariantUUID,
228                                     String name, Map<String, Object> profileInfo,
229                                     List<String> nsstInfoList, JsonArray capabilitiesList, Boolean preferReuse) {
230
231         def transactionId = requestId
232         logger.debug("transactionId is: " + transactionId)
233         String correlator = requestId
234         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
235         ObjectMapper objectMapper = new ObjectMapper()
236         String profileJson = objectMapper.writeValueAsString(profileInfo)
237         String nsstInfoListString = objectMapper.writeValueAsString(nsstInfoList)
238         //Prepare requestInfo object
239         JsonObject requestInfo = new JsonObject()
240         requestInfo.addProperty("transactionId", transactionId)
241         requestInfo.addProperty("requestId", requestId)
242         requestInfo.addProperty("callbackUrl", callbackUrl)
243         requestInfo.addProperty("sourceId", "SO")
244         requestInfo.addProperty("timeout", 600)
245         requestInfo.addProperty("numSolutions", 1)
246
247         //Prepare serviceInfo object
248         JsonObject ranNsstInfo = new JsonObject()
249         ranNsstInfo.addProperty("UUID", UUID)
250         ranNsstInfo.addProperty("invariantUUID", invariantUUID)
251         ranNsstInfo.addProperty("name", name)
252
253         JsonObject json = new JsonObject()
254         json.add("requestInfo", requestInfo)
255         json.add("NSTInfo", ranNsstInfo)
256         json.addProperty("serviceProfile", profileJson)
257         json.addProperty("NSSTInfo", nsstInfoListString)
258         json.add("subnetCapabilities", capabilitiesList)
259         json.addProperty("preferReuse", preferReuse)
260
261         return json.toString()
262     }
263
264     void processOofSelection(DelegateExecution execution) {
265         logger.debug(Prefix + "processOofSelection method start")
266         String oofResponse = execution.getVariable("nssiSelection_asyncCallbackResponse")
267         String requestStatus = jsonUtil.getJsonValue(oofResponse, "requestStatus")
268         if (requestStatus.equals("completed")) {
269             List<String> solution = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(oofResponse, "solutions"))
270             boolean existingNSI = jsonUtil.getJsonValue(solution.get(0), "existingNSI")
271             if (existingNSI) {
272                 def sharedNSISolution = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution")
273                 execution.setVariable("sharedTnNssiSolution", sharedNSISolution)
274                 logger.debug("sharedTnNssiSolution from OOF " + sharedNSISolution)
275                 String tnServiceInstanceId = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution.NSIId")
276                 execution.setVariable("tnServiceInstanceId", tnServiceInstanceId)
277                 org.onap.so.bpmn.core.domain.ServiceInstance serviceInstance = new org.onap.so.bpmn.core.domain.ServiceInstance();
278                 serviceInstance.setInstanceId(tnServiceInstanceId);
279                 ServiceDecomposition serviceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
280                 serviceDecomposition.setServiceInstance(serviceInstance);
281                 execution.setVariable("tnNsstServiceDecomposition", serviceDecomposition)
282                 execution.setVariable("isOofTnNssiSelected", true)
283             } else {
284                 def sliceProfiles = jsonUtil.getJsonValue(solution.get(0), "newNSISolution.sliceProfiles")
285                 execution.setVariable("tnConstituentSliceProfiles", sliceProfiles)
286                 execution.setVariable("isOofTnNssiSelected", false)
287                 logger.debug("tnConstituentSliceProfiles list from OOF " + sliceProfiles)
288             }
289         } else {
290             String statusMessage = jsonUtil.getJsonValue(oofResponse, "statusMessage")
291             logger.error("received failed status from oof " + statusMessage)
292             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a failed Async Response from OOF : " + statusMessage)
293         }
294
295         logger.debug(Prefix + "processOofSelection method finished")
296     }
297
298     void updateAAIOrchStatus(DelegateExecution execution) {
299         logger.debug("Start updateAAIOrchStatus")
300         String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
301         String orchStatus = execution.getVariable("orchestrationStatus")
302
303         try {
304             ServiceInstance si = new ServiceInstance()
305             si.setOrchestrationStatus(orchStatus)
306             AAIResourcesClient client = new AAIResourcesClient()
307             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(sliceServiceInstanceId))
308             client.update(uri, si)
309         } catch (BpmnError e) {
310             throw e
311         } catch (Exception ex) {
312             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
313             logger.info(msg)
314             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
315         }
316
317         logger.debug("Finish updateAAIOrchStatus")
318     }
319
320
321     void prepareUpdateJobStatus(DelegateExecution execution,
322                                 String status,
323                                 String progress,
324                                 String statusDescription) {
325         String serviceId = execution.getVariable("sliceServiceInstanceId")
326         String jobId = execution.getVariable("jobId")
327         String nsiId = execution.getVariable("nsiId")
328
329         ResourceOperationStatus roStatus = new ResourceOperationStatus()
330         roStatus.setServiceId(serviceId)
331         roStatus.setOperationId(jobId)
332         roStatus.setResourceTemplateUUID(nsiId)
333         roStatus.setOperType("Allocate")
334         roStatus.setProgress(progress)
335         roStatus.setStatus(status)
336         roStatus.setStatusDescription(statusDescription)
337         requestDBUtil.prepareUpdateResourceOperationStatus(execution, status)
338     }
339
340 }
341