2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.so.bpmn.infrastructure.scripts
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.so.bpmn.common.scripts.AbstractServiceTaskProcessor
35 import org.onap.so.bpmn.common.scripts.ExceptionUtil
36 import org.onap.so.bpmn.common.scripts.RequestDBUtil
37 import org.onap.so.bpmn.core.UrnPropertiesReader
38 import org.onap.so.bpmn.core.domain.ServiceDecomposition
39 import org.onap.so.bpmn.core.domain.ServiceProxy
40 import org.onap.so.bpmn.core.json.JsonUtils
41 import org.onap.so.db.request.beans.ResourceOperationStatus
42 import org.slf4j.Logger
43 import org.slf4j.LoggerFactory
44 import org.springframework.web.util.UriUtils
46 import static org.apache.commons.lang3.StringUtils.isBlank
48 class TnAllocateNssi extends AbstractServiceTaskProcessor {
49 String Prefix = "TNALLOC_"
51 ExceptionUtil exceptionUtil = new ExceptionUtil()
52 JsonUtils jsonUtil = new JsonUtils()
53 RequestDBUtil requestDBUtil = new RequestDBUtil()
54 JsonSlurper jsonSlurper = new JsonSlurper()
55 ObjectMapper objectMapper = new ObjectMapper()
56 TnNssmfUtils tnNssmfUtils = new TnNssmfUtils()
57 private static final Logger logger = LoggerFactory.getLogger(TnAllocateNssi.class)
59 void preProcessRequest(DelegateExecution execution) {
60 logger.debug("Start preProcessRequest")
61 execution.setVariable("prefix", Prefix)
65 execution.setVariable("startTime", System.currentTimeMillis())
67 msg = tnNssmfUtils.getExecutionInputParams(execution)
68 logger.debug("Allocate TN NSSI input parameters: " + msg)
70 tnNssmfUtils.setSdncCallbackUrl(execution, true)
71 logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
73 String additionalPropJsonStr = execution.getVariable("sliceParams")
75 String tnNssiId = execution.getVariable("serviceInstanceID")
76 if (isBlank(tnNssiId)) {
77 tnNssiId = UUID.randomUUID().toString()
80 String operationId = UUID.randomUUID().toString()
81 execution.setVariable("operationId", operationId)
83 logger.debug("Generate new TN NSSI ID:" + tnNssiId)
84 tnNssiId = UriUtils.encode(tnNssiId, "UTF-8")
85 execution.setVariable("sliceServiceInstanceId", tnNssiId)
87 String sliceServiceInstanceName = execution.getVariable("servicename")
88 execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
90 //additional properties
91 String sliceProfile = jsonUtil.getJsonValue(additionalPropJsonStr, "sliceProfile")
92 if (isBlank(sliceProfile)) {
93 msg = "Input sliceProfile is null"
95 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
97 execution.setVariable("sliceProfile", sliceProfile)
100 String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
101 if (isBlank(transportSliceNetworks)) {
102 msg = "Input transportSliceNetworks is null"
104 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
106 execution.setVariable("transportSliceNetworks", transportSliceNetworks)
108 logger.debug("transportSliceNetworks: " + transportSliceNetworks)
110 String nsiInfoStr = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
111 if (isBlank(nsiInfoStr)) {
112 msg = "Input nsiInfo is null"
114 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
116 execution.setVariable("nsiInfo", nsiInfoStr)
119 //nsiId is passed in from caller bpmn
120 //String nsiIdStr = jsonUtil.getJsonValue(nsiInfo, "nsiId")
121 //execution.setVariable("nsiId", nsiIdStr)
123 } catch (BpmnError e) {
125 } catch (Exception ex) {
126 msg = "Exception in preProcessRequest " + ex.getMessage()
128 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
130 logger.debug("Finish preProcessRequest")
134 void prepareDecomposeService(DelegateExecution execution) {
135 logger.debug("Start prepareDecomposeService")
137 String modelUuid = execution.getVariable("modelUuid")
138 if (isBlank(modelUuid)) {
139 msg = "Input modelUuid is null"
141 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
144 String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
145 if (isBlank(modelInvariantUuid)) {
146 msg = "Input modelInvariantUuid is null"
148 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
151 String serviceModelInfo = """{
152 "modelInvariantUuid":"${modelInvariantUuid}",
153 "modelUuid":"${modelUuid}",
156 execution.setVariable("ssServiceModelInfo", serviceModelInfo)
158 logger.debug("Finish prepareDecomposeService")
161 void processDecomposition(DelegateExecution execution) {
162 logger.debug("Start processDecomposition")
164 ServiceDecomposition tnNsstServiceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
165 logger.debug("tnNsstServiceDecomposition : " + tnNsstServiceDecomposition.toString())
166 //TN NSST decomposition
167 String tnModelVersion = tnNsstServiceDecomposition.getModelInfo().getModelVersion()
168 String tnModelName = tnNsstServiceDecomposition.getModelInfo().getModelName()
169 List<ServiceProxy> serviceProxyList = tnNsstServiceDecomposition.getServiceProxy()
170 List<String> nsstInfoList = new ArrayList<>()
171 for (ServiceProxy serviceProxy : serviceProxyList) {
172 String nsstModelUuid = serviceProxy.getModelInfo().getModelUuid()
173 String nsstModelInvariantUuid = serviceProxy.getModelInfo().getModelInvariantUuid()
174 String name = serviceProxy.getModelInfo().getModelName()
175 String nsstServiceModelInfo = """{
176 "UUID":"${nsstModelUuid}",
177 "invariantUUID":"${nsstModelInvariantUuid}",
180 nsstInfoList.add(nsstServiceModelInfo)
183 int maxIndex = nsstInfoList.size()
185 String msg = "Exception in TN NSST processDecomposition. There is no NSST associated with TN NSST "
187 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
189 execution.setVariable("tnNsstInfoList", nsstInfoList)
190 execution.setVariable("tnModelVersion", tnModelVersion)
191 execution.setVariable("tnModelName", tnModelName)
192 execution.setVariable("currentIndex", currentIndex)
193 execution.setVariable("maxIndex", maxIndex)
195 logger.debug("End processDecomposition")
198 void prepareOofSelection(DelegateExecution execution) {
199 logger.debug("Start prepareOofSelection")
201 String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
202 logger.debug("get NSSI option OOF Url: " + urlString)
203 //build oof request body
204 String requestId = execution.getVariable("msoRequestId")
205 String messageType = "NSISelectionResponse"
206 Map<String, Object> profileInfo = objectMapper.readValue(execution.getVariable("sliceProfile"), Map.class)
207 String modelUuid = execution.getVariable("modelUuid")
208 String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
209 String modelName = execution.getVariable("tnModelName")
210 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
211 List<String> nsstInfoList = objectMapper.readValue(execution.getVariable("nsstInfoList"), List.class)
212 JsonArray capabilitiesList = new JsonArray()
214 execution.setVariable("nssiSelection_Url", "/api/oof/selection/nsi/v1")
215 execution.setVariable("nssiSelection_messageType", messageType)
216 execution.setVariable("nssiSelection_correlator", requestId)
217 execution.setVariable("nssiSelection_timeout", timeout)
218 String oofRequest = buildSelectTnNssiRequest(requestId, messageType, modelUuid, modelInvariantUuid,
219 modelName, profileInfo, nsstInfoList, capabilitiesList, false)
220 execution.setVariable("nssiSelection_oofRequest", oofRequest)
222 logger.debug("Finish prepareOofSelection")
225 String buildSelectTnNssiRequest(String requestId, String messageType, String UUID, String invariantUUID,
226 String name, Map<String, Object> profileInfo,
227 List<String> nsstInfoList, JsonArray capabilitiesList, Boolean preferReuse) {
229 def transactionId = requestId
230 logger.debug("transactionId is: " + transactionId)
231 String correlator = requestId
232 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
233 ObjectMapper objectMapper = new ObjectMapper()
234 String profileJson = objectMapper.writeValueAsString(profileInfo)
235 String nsstInfoListString = objectMapper.writeValueAsString(nsstInfoList)
236 //Prepare requestInfo object
237 JsonObject requestInfo = new JsonObject()
238 requestInfo.addProperty("transactionId", transactionId)
239 requestInfo.addProperty("requestId", requestId)
240 requestInfo.addProperty("callbackUrl", callbackUrl)
241 requestInfo.addProperty("sourceId", "SO")
242 requestInfo.addProperty("timeout", 600)
243 requestInfo.addProperty("numSolutions", 1)
245 //Prepare serviceInfo object
246 JsonObject ranNsstInfo = new JsonObject()
247 ranNsstInfo.addProperty("UUID", UUID)
248 ranNsstInfo.addProperty("invariantUUID", invariantUUID)
249 ranNsstInfo.addProperty("name", name)
251 JsonObject json = new JsonObject()
252 json.add("requestInfo", requestInfo)
253 json.add("NSTInfo", ranNsstInfo)
254 json.addProperty("serviceProfile", profileJson)
255 json.addProperty("NSSTInfo", nsstInfoListString)
256 json.add("subnetCapabilities", capabilitiesList)
257 json.addProperty("preferReuse", preferReuse)
259 return json.toString()
262 void processOofSelection(DelegateExecution execution) {
263 logger.debug(Prefix + "processOofSelection method start")
264 String oofResponse = execution.getVariable("nssiSelection_asyncCallbackResponse")
265 String requestStatus = jsonUtil.getJsonValue(oofResponse, "requestStatus")
266 if (requestStatus.equals("completed")) {
267 List<String> solution = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(oofResponse, "solutions"))
268 boolean existingNSI = jsonUtil.getJsonValue(solution.get(0), "existingNSI")
270 def sharedNSISolution = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution")
271 execution.setVariable("sharedTnNssiSolution", sharedNSISolution)
272 logger.debug("sharedTnNssiSolution from OOF " + sharedNSISolution)
273 String tnServiceInstanceId = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution.NSIId")
274 execution.setVariable("tnServiceInstanceId", tnServiceInstanceId)
275 org.onap.so.bpmn.core.domain.ServiceInstance serviceInstance = new org.onap.so.bpmn.core.domain.ServiceInstance();
276 serviceInstance.setInstanceId(tnServiceInstanceId);
277 ServiceDecomposition serviceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
278 serviceDecomposition.setServiceInstance(serviceInstance);
279 execution.setVariable("tnNsstServiceDecomposition", serviceDecomposition)
280 execution.setVariable("isOofTnNssiSelected", true)
282 def sliceProfiles = jsonUtil.getJsonValue(solution.get(0), "newNSISolution.sliceProfiles")
283 execution.setVariable("tnConstituentSliceProfiles", sliceProfiles)
284 execution.setVariable("isOofTnNssiSelected", false)
285 logger.debug("tnConstituentSliceProfiles list from OOF " + sliceProfiles)
288 String statusMessage = jsonUtil.getJsonValue(oofResponse, "statusMessage")
289 logger.error("received failed status from oof " + statusMessage)
290 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a failed Async Response from OOF : " + statusMessage)
293 logger.debug(Prefix + "processOofSelection method finished")
296 void updateAAIOrchStatus(DelegateExecution execution) {
297 logger.debug("Start updateAAIOrchStatus")
298 String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
299 String orchStatus = execution.getVariable("orchestrationStatus")
302 ServiceInstance si = new ServiceInstance()
303 si.setOrchestrationStatus(orchStatus)
304 AAIResourcesClient client = new AAIResourcesClient()
305 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, sliceServiceInstanceId)
306 client.update(uri, si)
307 } catch (BpmnError e) {
309 } catch (Exception ex) {
310 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
312 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
315 logger.debug("Finish updateAAIOrchStatus")
319 void prepareUpdateJobStatus(DelegateExecution execution,
322 String statusDescription) {
323 String serviceId = execution.getVariable("sliceServiceInstanceId")
324 String jobId = execution.getVariable("jobId")
325 String nsiId = execution.getVariable("nsiId")
327 ResourceOperationStatus roStatus = new ResourceOperationStatus()
328 roStatus.setServiceId(serviceId)
329 roStatus.setOperationId(jobId)
330 roStatus.setResourceTemplateUUID(nsiId)
331 roStatus.setOperType("Allocate")
332 roStatus.setProgress(progress)
333 roStatus.setStatus(status)
334 roStatus.setStatusDescription(statusDescription)
335 requestDBUtil.prepareUpdateResourceOperationStatus(execution, status)