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.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
48 import static org.apache.commons.lang3.StringUtils.isBlank
50 class TnAllocateNssi extends AbstractServiceTaskProcessor {
51 String Prefix = "TNALLOC_"
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)
61 void preProcessRequest(DelegateExecution execution) {
62 logger.debug("Start preProcessRequest")
63 execution.setVariable("prefix", Prefix)
67 execution.setVariable("startTime", System.currentTimeMillis())
69 msg = tnNssmfUtils.getExecutionInputParams(execution)
70 logger.debug("Allocate TN NSSI input parameters: " + msg)
72 tnNssmfUtils.setSdncCallbackUrl(execution, true)
73 logger.debug("SDNC Callback URL: " + execution.getVariable("sdncCallbackUrl"))
75 String additionalPropJsonStr = execution.getVariable("sliceParams")
77 String tnNssiId = execution.getVariable("serviceInstanceID")
78 if (isBlank(tnNssiId)) {
79 tnNssiId = UUID.randomUUID().toString()
82 String operationId = UUID.randomUUID().toString()
83 execution.setVariable("operationId", operationId)
85 logger.debug("Generate new TN NSSI ID:" + tnNssiId)
86 tnNssiId = UriUtils.encode(tnNssiId, "UTF-8")
87 execution.setVariable("sliceServiceInstanceId", tnNssiId)
89 String sliceServiceInstanceName = execution.getVariable("servicename")
90 execution.setVariable("sliceServiceInstanceName", sliceServiceInstanceName)
92 //additional properties
93 String sliceProfile = jsonUtil.getJsonValue(additionalPropJsonStr, "sliceProfile")
94 if (isBlank(sliceProfile)) {
95 msg = "Input sliceProfile is null"
97 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
99 execution.setVariable("sliceProfile", sliceProfile)
102 String transportSliceNetworks = jsonUtil.getJsonValue(additionalPropJsonStr, "transportSliceNetworks")
103 if (isBlank(transportSliceNetworks)) {
104 msg = "Input transportSliceNetworks is null"
106 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
108 execution.setVariable("transportSliceNetworks", transportSliceNetworks)
110 logger.debug("transportSliceNetworks: " + transportSliceNetworks)
112 String nsiInfoStr = jsonUtil.getJsonValue(additionalPropJsonStr, "nsiInfo")
113 if (isBlank(nsiInfoStr)) {
114 msg = "Input nsiInfo is null"
116 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
118 execution.setVariable("nsiInfo", nsiInfoStr)
121 //nsiId is passed in from caller bpmn
122 //String nsiIdStr = jsonUtil.getJsonValue(nsiInfo, "nsiId")
123 //execution.setVariable("nsiId", nsiIdStr)
125 } catch (BpmnError e) {
127 } catch (Exception ex) {
128 msg = "Exception in preProcessRequest " + ex.getMessage()
130 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
132 logger.debug("Finish preProcessRequest")
136 void prepareDecomposeService(DelegateExecution execution) {
137 logger.debug("Start prepareDecomposeService")
139 String modelUuid = execution.getVariable("modelUuid")
140 if (isBlank(modelUuid)) {
141 msg = "Input modelUuid is null"
143 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
146 String modelInvariantUuid = execution.getVariable("modelInvariantUuid")
147 if (isBlank(modelInvariantUuid)) {
148 msg = "Input modelInvariantUuid is null"
150 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
153 String serviceModelInfo = """{
154 "modelInvariantUuid":"${modelInvariantUuid}",
155 "modelUuid":"${modelUuid}",
158 execution.setVariable("ssServiceModelInfo", serviceModelInfo)
160 logger.debug("Finish prepareDecomposeService")
163 void processDecomposition(DelegateExecution execution) {
164 logger.debug("Start processDecomposition")
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}",
182 nsstInfoList.add(nsstServiceModelInfo)
185 int maxIndex = nsstInfoList.size()
187 String msg = "Exception in TN NSST processDecomposition. There is no NSST associated with TN NSST "
189 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
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)
197 logger.debug("End processDecomposition")
200 void prepareOofSelection(DelegateExecution execution) {
201 logger.debug("Start prepareOofSelection")
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()
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)
224 logger.debug("Finish prepareOofSelection")
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) {
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)
247 //Prepare serviceInfo object
248 JsonObject ranNsstInfo = new JsonObject()
249 ranNsstInfo.addProperty("UUID", UUID)
250 ranNsstInfo.addProperty("invariantUUID", invariantUUID)
251 ranNsstInfo.addProperty("name", name)
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)
261 return json.toString()
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")
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)
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)
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)
295 logger.debug(Prefix + "processOofSelection method finished")
298 void updateAAIOrchStatus(DelegateExecution execution) {
299 logger.debug("Start updateAAIOrchStatus")
300 String sliceServiceInstanceId = execution.getVariable("sliceServiceInstanceId")
301 String orchStatus = execution.getVariable("orchestrationStatus")
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) {
311 } catch (Exception ex) {
312 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
314 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
317 logger.debug("Finish updateAAIOrchStatus")
321 void prepareUpdateJobStatus(DelegateExecution execution,
324 String statusDescription) {
325 String serviceId = execution.getVariable("sliceServiceInstanceId")
326 String jobId = execution.getVariable("jobId")
327 String nsiId = execution.getVariable("nsiId")
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)