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.AAIResourcesClient
31 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
32 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
33 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
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 = jsonUtil.getJsonValue(additionalPropJsonStr, "serviceInstanceID") //for debug
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("serviceModelInfo", 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)
196 logger.debug("End processDecomposition")
199 void prepareOofSelection(DelegateExecution execution) {
200 logger.debug("Start prepareOofSelection")
202 String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
203 logger.debug("get NSSI option OOF Url: " + urlString)
204 //build oof request body
205 String requestId = execution.getVariable("msoRequestId")
206 String messageType = "NSISelectionResponse"
207 Map<String, Object> profileInfo = objectMapper.readValue(execution.getVariable("sliceProfile"), Map.class)
208 String modelUuid = execution.getVariable("modelUuid")
209 String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
210 String modelName = execution.getVariable("tnModelName")
211 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
212 List<String> nsstInfoList = objectMapper.readValue(execution.getVariable("nsstInfoList"), List.class)
213 JsonArray capabilitiesList = new JsonArray()
215 execution.setVariable("nssiSelection_Url", "/api/oof/selection/nsi/v1")
216 execution.setVariable("nssiSelection_messageType", messageType)
217 execution.setVariable("nssiSelection_correlator", requestId)
218 execution.setVariable("nssiSelection_timeout", timeout)
219 String oofRequest = buildSelectTnNssiRequest(requestId, messageType, modelUuid, modelInvariantUuid,
220 modelName, profileInfo, nsstInfoList, capabilitiesList, false)
221 execution.setVariable("nssiSelection_oofRequest", oofRequest)
223 logger.debug("Finish prepareOofSelection")
226 String buildSelectTnNssiRequest(String requestId, String messageType, String UUID, String invariantUUID,
227 String name, Map<String, Object> profileInfo,
228 List<String> nsstInfoList, JsonArray capabilitiesList, Boolean preferReuse) {
230 def transactionId = requestId
231 logger.debug("transactionId is: " + transactionId)
232 String correlator = requestId
233 String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
234 ObjectMapper objectMapper = new ObjectMapper()
235 String profileJson = objectMapper.writeValueAsString(profileInfo)
236 String nsstInfoListString = objectMapper.writeValueAsString(nsstInfoList)
237 //Prepare requestInfo object
238 JsonObject requestInfo = new JsonObject()
239 requestInfo.addProperty("transactionId", transactionId)
240 requestInfo.addProperty("requestId", requestId)
241 requestInfo.addProperty("callbackUrl", callbackUrl)
242 requestInfo.addProperty("sourceId", "SO")
243 requestInfo.addProperty("timeout", 600)
244 requestInfo.addProperty("numSolutions", 1)
246 //Prepare serviceInfo object
247 JsonObject ranNsstInfo = new JsonObject()
248 ranNsstInfo.addProperty("UUID", UUID)
249 ranNsstInfo.addProperty("invariantUUID", invariantUUID)
250 ranNsstInfo.addProperty("name", name)
252 JsonObject json = new JsonObject()
253 json.add("requestInfo", requestInfo)
254 json.add("NSTInfo", ranNsstInfo)
255 json.addProperty("serviceProfile", profileJson)
256 json.addProperty("NSSTInfo", nsstInfoListString)
257 json.add("subnetCapabilities", capabilitiesList)
258 json.addProperty("preferReuse", preferReuse)
260 return json.toString()
263 void processOofSelection(DelegateExecution execution) {
264 logger.debug(Prefix + "processOofSelection method start")
265 String oofResponse = execution.getVariable("nssiSelection_asyncCallbackResponse")
266 String requestStatus = jsonUtil.getJsonValue(oofResponse, "requestStatus")
267 if (requestStatus.equals("completed")) {
268 List<String> solution = jsonUtil.StringArrayToList(jsonUtil.getJsonValue(oofResponse, "solutions"))
269 boolean existingNSI = jsonUtil.getJsonValue(solution.get(0), "existingNSI")
271 def sharedNSISolution = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution")
272 execution.setVariable("sharedTnNssiSolution", sharedNSISolution)
273 logger.debug("sharedTnNssiSolution from OOF " + sharedNSISolution)
274 String tnServiceInstanceId = jsonUtil.getJsonValue(solution.get(0), "sharedNSISolution.NSIId")
275 execution.setVariable("tnServiceInstanceId", tnServiceInstanceId)
276 org.onap.so.bpmn.core.domain.ServiceInstance serviceInstance = new org.onap.so.bpmn.core.domain.ServiceInstance();
277 serviceInstance.setInstanceId(tnServiceInstanceId);
278 ServiceDecomposition serviceDecomposition = execution.getVariable("tnNsstServiceDecomposition")
279 serviceDecomposition.setServiceInstance(serviceInstance);
280 execution.setVariable("tnNsstServiceDecomposition", serviceDecomposition)
281 execution.setVariable("isOofTnNssiSelected", true)
283 def sliceProfiles = jsonUtil.getJsonValue(solution.get(0), "newNSISolution.sliceProfiles")
284 execution.setVariable("tnConstituentSliceProfiles", sliceProfiles)
285 execution.setVariable("isOofTnNssiSelected", false)
286 logger.debug("tnConstituentSliceProfiles list from OOF " + sliceProfiles)
289 String statusMessage = jsonUtil.getJsonValue(oofResponse, "statusMessage")
290 logger.error("received failed status from oof " + statusMessage)
291 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Received a failed Async Response from OOF : " + statusMessage)
294 logger.debug(Prefix + "processOofSelection method finished")
297 void updateAAIOrchStatus(DelegateExecution execution) {
298 logger.debug("Start updateAAIOrchStatus")
299 String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
300 String orchStatus = execution.getVariable("orchestrationStatus")
303 ServiceInstance si = new ServiceInstance()
304 si.setOrchestrationStatus(orchStatus)
305 AAIResourcesClient client = new AAIResourcesClient()
306 AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(sliceServiceInstanceId))
307 client.update(uri, si)
308 } catch (BpmnError e) {
310 } catch (Exception ex) {
311 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
313 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
316 logger.debug("Finish updateAAIOrchStatus")
320 void prepareUpdateJobStatus(DelegateExecution execution,
323 String statusDescription) {
324 String modelUuid = execution.getVariable("modelUuid")
325 String ssInstanceId = execution.getVariable("sliceServiceInstanceId")
326 String jobId = execution.getVariable("jobId")
327 String nsiId = execution.getVariable("nsiId")
329 ResourceOperationStatus roStatus = new ResourceOperationStatus()
330 roStatus.setServiceId(nsiId)
331 roStatus.setOperationId(jobId)
332 roStatus.setResourceTemplateUUID(modelUuid)
333 roStatus.setResourceInstanceID(ssInstanceId)
334 roStatus.setOperType("ALLOCATE")
335 roStatus.setProgress(progress)
336 roStatus.setStatus(status)
337 roStatus.setStatusDescription(statusDescription)
338 requestDBUtil.prepareUpdateResourceOperationStatus(execution, roStatus)