2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 # Copyright (c) 2020, CMCC Technologies Co., Ltd.
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 static org.apache.commons.lang3.StringUtils.*
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.aai.domain.yang.ServiceInstance
27 import org.onap.aaiclient.client.aai.AAIResourcesClient
28 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
29 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
30 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
31 import org.onap.logging.filter.base.ErrorCode
32 import org.onap.so.beans.nsmf.SliceTaskParams
33 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
34 import org.onap.so.beans.nsmf.oof.TemplateInfo
35 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
36 import org.onap.so.bpmn.common.scripts.ExceptionUtil
37 import org.onap.so.bpmn.common.scripts.MsoUtils
38 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
39 import org.onap.so.bpmn.common.scripts.OofUtils
40 import org.onap.so.bpmn.core.UrnPropertiesReader
41 import org.onap.so.bpmn.core.json.JsonUtils
42 import org.onap.so.db.request.beans.OrchestrationTask
43 import org.onap.so.logger.LoggingAnchor
44 import org.onap.so.logger.MessageEnum
45 import org.slf4j.Logger
46 import org.slf4j.LoggerFactory
47 import org.springframework.web.util.UriUtils
48 import com.fasterxml.jackson.databind.ObjectMapper
49 import groovy.json.JsonSlurper
51 public class CreateSliceService extends AbstractServiceTaskProcessor {
52 String Prefix = "CRESS_"
54 ExceptionUtil exceptionUtil = new ExceptionUtil()
55 JsonUtils jsonUtil = new JsonUtils()
56 JsonSlurper jsonSlurper = new JsonSlurper()
57 ObjectMapper objectMapper = new ObjectMapper()
58 OofUtils oofUtils = new OofUtils()
59 NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
60 AAIResourcesClient client = getAAIClient()
62 private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
64 public void preProcessRequest(DelegateExecution execution) {
65 logger.debug("Start preProcessRequest")
66 execution.setVariable("prefix", Prefix)
70 String ssRequest = execution.getVariable("bpmnRequest")
71 logger.debug(ssRequest)
73 String requestId = execution.getVariable("mso-request-id")
74 execution.setVariable("msoRequestId", requestId)
75 logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
77 String serviceInstanceId = execution.getVariable("serviceInstanceId")
78 if (isBlank(serviceInstanceId)) {
79 serviceInstanceId = UUID.randomUUID().toString()
82 String operationId = UUID.randomUUID().toString()
83 execution.setVariable("operationId", operationId)
85 logger.debug("Generated new Service Instance:" + serviceInstanceId)
86 serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
87 execution.setVariable("serviceInstanceId", serviceInstanceId)
90 String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
91 if (isBlank(globalSubscriberId)) {
92 msg = "Input globalSubscriberId' is null"
93 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
95 execution.setVariable("globalSubscriberId", globalSubscriberId)
99 execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
100 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
101 execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
102 String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
103 if (isBlank(productFamilyId)) {
104 msg = "Input productFamilyId is null"
106 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
108 execution.setVariable("productFamilyId", productFamilyId)
112 String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
113 if (isBlank(serviceModelInfo)) {
114 msg = "Input serviceModelInfo is null"
116 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
118 execution.setVariable("serviceModelInfo", serviceModelInfo)
121 logger.debug("modelInfo: " + serviceModelInfo)
124 String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
125 if (isBlank(subscriptionServiceType)) {
126 msg = "Input subscriptionServiceType is null"
128 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
130 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
132 logger.debug("subscriptionServiceType: " + subscriptionServiceType)
135 * Extracting User Parameters from incoming Request and converting into a Map
137 Map reqMap = jsonSlurper.parseText(ssRequest)
140 def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
142 Map<String, String> inputMap = [:]
143 if (userParamsList) {
144 for (def i = 0; i < userParamsList.size(); i++) {
145 def userParams1 = userParamsList.get(i)
146 userParams1.each { param -> inputMap.put(param.key, param.value) }
150 logger.debug("User Input Parameters map: " + inputMap.toString())
151 String uuiRequest = inputMap.get("UUIRequest")
152 Map uuiReqMap = jsonSlurper.parseText(uuiRequest) as Map
153 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
154 Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
155 Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
157 def serviceProfile = [:]
158 for(entry in requestInputs) {
159 serviceProfile[entry.key] = entry.value
162 execution.setVariable("serviceInputParams", inputMap)
163 execution.setVariable("uuiRequest", uuiRequest)
164 execution.setVariable("se" +
165 "rviceProfile", serviceProfile)
168 //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
169 //execution.setVariable("failExists", true)
171 } catch (BpmnError e) {
173 } catch (Exception ex) {
174 msg = "Exception in preProcessRequest " + ex.getMessage()
176 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
178 logger.debug("Finish preProcessRequest")
185 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
186 logger.debug("Start prepareInitServiceOperationStatus")
188 String serviceId = execution.getVariable("serviceInstanceId")
189 String operationId = execution.getVariable("operationId")
190 String operationType = "CREATE"
191 String userId = execution.getVariable("globalSubscriberId")
192 String result = "processing"
193 String progress = "0"
195 String operationContent = "Prepare service creation"
196 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
197 serviceId = UriUtils.encode(serviceId,"UTF-8")
198 execution.setVariable("serviceInstanceId", serviceId)
199 execution.setVariable("operationType", operationType)
201 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
202 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
203 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
204 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
205 Map<String, String> CSSOS_headerMap = [:]
206 CSSOS_headerMap.put("content-type", "application/soap+xml")
207 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
208 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
209 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
212 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
213 xmlns:ns="http://org.onap.so/requestsdb">
216 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
217 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
218 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
219 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
220 <userId>${MsoUtils.xmlEscape(userId)}</userId>
221 <result>${MsoUtils.xmlEscape(result)}</result>
222 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
223 <progress>${MsoUtils.xmlEscape(progress)}</progress>
224 <reason>${MsoUtils.xmlEscape(reason)}</reason>
225 </ns:initServiceOperationStatus>
227 </soapenv:Envelope>"""
229 payload = utils.formatXml(payload)
230 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
231 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
233 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
234 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
235 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
237 logger.debug("Finish prepareInitServiceOperationStatus")
241 * prepare create OrchestrationTask
244 public void prepareCreateOrchestrationTask(DelegateExecution execution) {
245 logger.debug("Start createOrchestrationTask")
246 String taskId = execution.getBusinessKey()
247 execution.setVariable("orchestrationTaskId", taskId)
248 logger.debug("BusinessKey: " + taskId)
249 String serviceInstanceId = execution.getVariable("serviceInstanceId")
250 String serviceInstanceName = execution.getVariable("serviceInstanceName")
251 String taskName = "SliceServiceTask"
252 String taskStatus = "Planning"
253 String isManual = "false"
254 String requestMethod = "POST"
255 execution.setVariable("CSSOT_taskId", taskId)
256 execution.setVariable("CSSOT_name", taskName)
257 execution.setVariable("CSSOT_status", taskStatus)
258 execution.setVariable("CSSOT_isManual", isManual)
259 execution.setVariable("CSSOT_requestMethod", requestMethod)
261 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
263 SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
264 sliceTaskParams.setServiceId(serviceInstanceId)
265 sliceTaskParams.setServiceName(serviceInstanceName)
266 sliceTaskParams.setServiceProfile(serviceProfile)
268 execution.setVariable("sliceTaskParams", sliceTaskParams)
270 //todo:----------------------------------------
271 // String paramJson = sliceTaskParams.convertToJson()
272 // execution.setVariable("CSSOT_paramJson", paramJson)
273 /*-------------------------------------------*/
275 logger.debug("Finish createOrchestrationTask")
279 * send sync response to csmf
282 public void sendSyncResponse(DelegateExecution execution) {
283 logger.debug("Start sendSyncResponse")
285 String operationId = execution.getVariable("operationId")
286 String serviceInstanceId = execution.getVariable("serviceInstanceId")
287 // RESTResponse for API Handler (APIH) Reply Task
288 String createServiceRestRequest = """
291 "serviceId":"${serviceInstanceId}",
292 "operationId":"${operationId}"
297 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
298 sendWorkflowResponse(execution, 202, createServiceRestRequest)
299 execution.setVariable("sentSyncResponse", true)
300 } catch (Exception e) {
301 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
303 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
305 logger.debug("Finish sendSyncResponse")
308 public void prepareSelectNSTRequest(DelegateExecution execution) {
309 logger.debug("Start prepareSelectNSTRequest")
310 String requestId = execution.getVariable("msoRequestId")
311 String messageType = "NSTSelectionResponse"
312 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
313 execution.setVariable("nstSelectionUrl", "/api/oof/v1/selection/nst")
314 execution.setVariable("nstSelection_messageType", messageType)
315 execution.setVariable("nstSelection_correlator", requestId)
316 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
317 execution.setVariable("nstSelection_timeout", timeout)
318 String oofRequest = oofUtils.buildSelectNSTRequest(requestId, messageType, serviceProfile)
319 execution.setVariable("nstSelection_oofRequest", oofRequest)
320 logger.debug("Finish prepareSelectNSTRequest")
325 * process async response of oof, put the {@solutions} at {@nstSolution}
328 public void processNSTSolutions(DelegateExecution execution) {
329 Map<String, Object> nstSolution
331 logger.debug("Start processing NSTSolutions")
332 Map<String, Object> resMap =
333 objectMapper.readValue(execution.getVariable("nstSelection_oofResponse") as String,
336 List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
337 nstSolution = nstSolutions.get(0)
338 execution.setVariable("nstSolution", nstSolution)
340 //set nst info into sliceTaskParams
341 SliceTaskParamsAdapter sliceTaskParams =
342 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
343 TemplateInfo nstInfo = new TemplateInfo()
344 nstInfo.setUUID(nstSolution.get("UUID") as String)
345 nstInfo.setInvariantUUID(nstSolution.get("invariantUUID") as String)
346 nstInfo.setName(nstSolution.get("name") as String)
348 sliceTaskParams.setNSTInfo(nstInfo)
350 execution.setVariable("sliceTaskParams", sliceTaskParams)
352 } catch (Exception ex) {
353 logger.debug( "Failed to get NST solution suggested by OOF.")
354 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
359 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
360 logger.debug("Start prepareUpdateOrchestrationTask")
361 String requestMethod = "PUT"
362 String taskStatus = execution.getVariable("taskStatus")
363 SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
364 String paramJson = sliceTaskParams.convertToJson()
365 execution.setVariable("CSSOT_status", taskStatus)
366 execution.setVariable("CSSOT_paramJson", paramJson)
367 execution.setVariable("CSSOT_requestMethod", requestMethod)
368 logger.debug("Finish prepareUpdateOrchestrationTask")
372 public void prepareGetUserOptions(DelegateExecution execution) {
373 logger.debug("Start prepareGetUserOptions")
374 String requestMethod = "GET"
375 execution.setVariable("taskAction", "commit")
376 String taskAction = execution.getVariable("taskAction")
377 logger.debug("task action is: " + taskAction)
378 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
379 String msg = "Unknown task action: " + taskAction
381 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
383 execution.setVariable("CSSOT_requestMethod", requestMethod)
384 logger.debug("Finish prepareGetUserOptions")
387 public void processUserOptions(DelegateExecution execution) {
388 logger.debug("Start processUserOptions")
389 String response = execution.getVariable("CSSOT_dbResponse")
390 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
391 String paramJson = orchestrationTask.getParams()
392 logger.debug("paramJson: " + paramJson)
393 SliceTaskParams sliceTaskParams = new SliceTaskParams()
394 sliceTaskParams.convertFromJson(paramJson)
395 execution.setVariable("sliceTaskParams", sliceTaskParams)
396 logger.debug("Finish processUserOptions")
399 public void updateAAIOrchStatus(DelegateExecution execution) {
400 logger.debug("Start updateAAIOrchStatus")
401 String serviceInstanceId = execution.getVariable("serviceInstanceId")
402 String orchStatus = execution.getVariable("orchestrationStatus")
405 ServiceInstance si = new ServiceInstance()
406 si.setOrchestrationStatus(orchStatus)
407 AAIResourcesClient client = new AAIResourcesClient()
408 AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
409 client.update(uri, si)
410 } catch (BpmnError e) {
412 } catch (Exception ex) {
413 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
415 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
418 logger.debug("Finish updateAAIOrchStatus")
421 public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
422 logger.debug("Start preUpdateServiceOperationStatus")
424 String serviceId = execution.getVariable("serviceInstanceId")
425 String operationId = execution.getVariable("operationId")
426 String operationType = execution.getVariable("operationType")
427 String userId = execution.getVariable("globalSubscriberId")
428 String result = execution.getVariable("operationResult")
429 String progress = execution.getVariable("operationProgress")
430 String reason = execution.getVariable("operationReason")
431 String operationContent = "service: " + result + " progress: " + progress
434 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
435 xmlns:ns="http://org.onap.so/requestsdb">
438 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
439 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
440 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
441 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
442 <userId>${MsoUtils.xmlEscape(userId)}</userId>
443 <result>${MsoUtils.xmlEscape(result)}</result>
444 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
445 <progress>${MsoUtils.xmlEscape(progress)}</progress>
446 <reason>${MsoUtils.xmlEscape(reason)}</reason>
447 </ns:initServiceOperationStatus>
449 </soapenv:Envelope>"""
451 payload = utils.formatXml(payload)
452 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
453 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
456 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
457 "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
458 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
460 logger.debug("Finish preUpdateServiceOperationStatus")
465 public void prepareCompletionRequest (DelegateExecution execution) {
466 logger.trace("Start prepareCompletionRequest")
468 String requestId = execution.getVariable("msoRequestId")
469 String serviceInstanceId = execution.getVariable("serviceInstanceId")
470 String source = execution.getVariable("source")
472 String msoCompletionRequest =
473 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
474 xmlns:ns="http://org.onap/so/request/types/v1">
475 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
476 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
477 <action>CREATE</action>
478 <source>${MsoUtils.xmlEscape(source)}</source>
480 <status-message>Service Instance was created successfully.</status-message>
481 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
482 <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
483 </aetgt:MsoCompletionRequest>"""
486 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
488 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
489 logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
491 } catch (Exception ex) {
492 String msg = " Exception in prepareCompletion:" + ex.getMessage()
494 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
496 logger.trace("Finish prepareCompletionRequest")