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 org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
25 import static org.apache.commons.lang3.StringUtils.*
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.ServiceInstance
29 import org.onap.aaiclient.client.aai.AAIResourcesClient
30 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
31 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
32 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
33 import org.onap.logging.filter.base.ErrorCode
34 import org.onap.so.beans.nsmf.SliceTaskParams
35 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
36 import org.onap.so.beans.nsmf.oof.TemplateInfo
37 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
38 import org.onap.so.bpmn.common.scripts.ExceptionUtil
39 import org.onap.so.bpmn.common.scripts.MsoUtils
40 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
41 import org.onap.so.bpmn.common.scripts.OofUtils
42 import org.onap.so.bpmn.core.UrnPropertiesReader
43 import org.onap.so.bpmn.core.json.JsonUtils
44 import org.onap.so.db.request.beans.OrchestrationTask
45 import org.onap.so.logger.LoggingAnchor
46 import org.onap.so.logger.MessageEnum
47 import org.slf4j.Logger
48 import org.slf4j.LoggerFactory
49 import org.springframework.web.util.UriUtils
50 import com.fasterxml.jackson.databind.ObjectMapper
51 import groovy.json.JsonSlurper
53 public class CreateSliceService extends AbstractServiceTaskProcessor {
54 String Prefix = "CRESS_"
56 ExceptionUtil exceptionUtil = new ExceptionUtil()
58 JsonUtils jsonUtil = new JsonUtils()
60 JsonSlurper jsonSlurper = new JsonSlurper()
62 ObjectMapper objectMapper = new ObjectMapper()
64 OofUtils oofUtils = new OofUtils()
66 AAIResourcesClient client = getAAIClient()
68 private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
70 public void preProcessRequest(DelegateExecution execution) {
71 logger.debug("Start preProcessRequest")
72 execution.setVariable("prefix", Prefix)
76 String ssRequest = execution.getVariable("bpmnRequest")
77 logger.debug(ssRequest)
79 String requestId = execution.getVariable("mso-request-id")
80 execution.setVariable("msoRequestId", requestId)
81 logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
83 String serviceInstanceId = execution.getVariable("serviceInstanceId")
84 if (isBlank(serviceInstanceId)) {
85 serviceInstanceId = UUID.randomUUID().toString()
88 String operationId = UUID.randomUUID().toString()
89 execution.setVariable("operationId", operationId)
91 logger.debug("Generated new Service Instance:" + serviceInstanceId)
92 serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
93 execution.setVariable("serviceInstanceId", serviceInstanceId)
96 String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
97 if (isBlank(globalSubscriberId)) {
98 msg = "Input globalSubscriberId' is null"
99 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
101 execution.setVariable("globalSubscriberId", globalSubscriberId)
105 execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
106 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
107 execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
108 String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
109 if (isBlank(productFamilyId)) {
110 msg = "Input productFamilyId is null"
112 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
114 execution.setVariable("productFamilyId", productFamilyId)
118 String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
119 if (isBlank(serviceModelInfo)) {
120 msg = "Input serviceModelInfo is null"
122 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
124 execution.setVariable("serviceModelInfo", serviceModelInfo)
127 logger.debug("modelInfo: " + serviceModelInfo)
130 String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
131 if (isBlank(subscriptionServiceType)) {
132 msg = "Input subscriptionServiceType is null"
134 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
136 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
138 logger.debug("subscriptionServiceType: " + subscriptionServiceType)
141 * Extracting User Parameters from incoming Request and converting into a Map
143 Map reqMap = jsonSlurper.parseText(ssRequest)
146 def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
148 Map<String, String> inputMap = [:]
149 if (userParamsList) {
150 for (def i = 0; i < userParamsList.size(); i++) {
151 def userParams1 = userParamsList.get(i)
152 userParams1.each { param -> inputMap.put(param.key, param.value) }
156 logger.debug("User Input Parameters map: " + inputMap.toString())
157 String uuiRequest = inputMap.get("UUIRequest")
158 Map uuiReqMap = jsonSlurper.parseText(uuiRequest) as Map
159 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
160 Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
161 Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
163 def serviceProfile = [:]
164 for(entry in requestInputs) {
165 serviceProfile[entry.key] = entry.value
168 execution.setVariable("serviceInputParams", inputMap)
169 execution.setVariable("uuiRequest", uuiRequest)
170 execution.setVariable("serviceProfile", serviceProfile)
173 //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
174 //execution.setVariable("failExists", true)
176 } catch (BpmnError e) {
178 } catch (Exception ex) {
179 msg = "Exception in preProcessRequest " + ex.getMessage()
181 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
183 logger.debug("Finish preProcessRequest")
190 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
191 logger.debug("Start prepareInitServiceOperationStatus")
193 String serviceId = execution.getVariable("serviceInstanceId")
194 String operationId = execution.getVariable("operationId")
195 String operationType = "CREATE"
196 String userId = execution.getVariable("globalSubscriberId")
197 String result = "processing"
198 String progress = "0"
200 String operationContent = "Prepare service creation"
201 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
202 serviceId = UriUtils.encode(serviceId,"UTF-8")
203 execution.setVariable("serviceInstanceId", serviceId)
204 execution.setVariable("operationType", operationType)
206 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
207 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
208 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
209 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
210 Map<String, String> CSSOS_headerMap = [:]
211 CSSOS_headerMap.put("content-type", "application/soap+xml")
212 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
213 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
214 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
217 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
218 xmlns:ns="http://org.onap.so/requestsdb">
221 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
222 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
223 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
224 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
225 <userId>${MsoUtils.xmlEscape(userId)}</userId>
226 <result>${MsoUtils.xmlEscape(result)}</result>
227 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
228 <progress>${MsoUtils.xmlEscape(progress)}</progress>
229 <reason>${MsoUtils.xmlEscape(reason)}</reason>
230 </ns:initServiceOperationStatus>
232 </soapenv:Envelope>"""
234 payload = utils.formatXml(payload)
235 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
236 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
238 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
239 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
240 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
242 logger.debug("Finish prepareInitServiceOperationStatus")
246 * prepare create OrchestrationTask
249 public void prepareCreateOrchestrationTask(DelegateExecution execution) {
250 logger.debug("Start createOrchestrationTask")
251 String taskId = execution.getBusinessKey()
252 execution.setVariable("orchestrationTaskId", taskId)
253 logger.debug("BusinessKey: " + taskId)
254 String serviceInstanceId = execution.getVariable("serviceInstanceId")
255 String serviceInstanceName = execution.getVariable("serviceInstanceName")
256 String taskName = "SliceServiceTask"
257 String taskStatus = "Planning"
258 String isManual = "false"
259 String requestMethod = "POST"
260 execution.setVariable("CSSOT_taskId", taskId)
261 execution.setVariable("CSSOT_name", taskName)
262 execution.setVariable("CSSOT_status", taskStatus)
263 execution.setVariable("CSSOT_isManual", isManual)
264 execution.setVariable("CSSOT_requestMethod", requestMethod)
266 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
268 SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
269 sliceTaskParams.setServiceId(serviceInstanceId)
270 sliceTaskParams.setServiceName(serviceInstanceName)
271 sliceTaskParams.setServiceProfile(serviceProfile)
273 execution.setVariable("sliceTaskParams", sliceTaskParams)
275 String paramJson = sliceTaskParams.convertToJson()
276 execution.setVariable("CSSOT_paramJson", paramJson)
278 logger.debug("Finish createOrchestrationTask")
282 * send sync response to csmf
285 public void sendSyncResponse(DelegateExecution execution) {
286 logger.debug("Start sendSyncResponse")
288 String operationId = execution.getVariable("operationId")
289 String serviceInstanceId = execution.getVariable("serviceInstanceId")
290 // RESTResponse for API Handler (APIH) Reply Task
291 String createServiceRestRequest = """
294 "serviceId":"${serviceInstanceId}",
295 "operationId":"${operationId}"
300 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
301 sendWorkflowResponse(execution, 202, createServiceRestRequest)
302 execution.setVariable("sentSyncResponse", true)
303 } catch (Exception e) {
304 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
306 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
308 logger.debug("Finish sendSyncResponse")
311 public void prepareSelectNSTRequest(DelegateExecution execution) {
312 logger.debug("Start prepareSelectNSTRequest")
313 String requestId = execution.getVariable("msoRequestId")
314 String messageType = "NSTSelectionResponse"
315 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
316 execution.setVariable("nstSelectionUrl", "/api/oof/v1/selection/nst")
317 execution.setVariable("nstSelection_messageType", messageType)
318 execution.setVariable("nstSelection_correlator", requestId)
319 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
320 execution.setVariable("nstSelection_timeout", timeout)
321 String oofRequest = oofUtils.buildSelectNSTRequest(requestId, messageType, serviceProfile)
322 execution.setVariable("nstSelection_oofRequest", oofRequest)
323 logger.debug("Finish prepareSelectNSTRequest")
328 * process async response of oof, put the {@solutions} at {@nstSolution}
331 public void processNSTSolutions(DelegateExecution execution) {
332 Map<String, Object> nstSolution
334 logger.debug("Start processing NSTSolutions")
335 Map<String, Object> resMap =
336 objectMapper.readValue(execution.getVariable("nstSelection_oofResponse") as String,
339 List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
340 nstSolution = nstSolutions.get(0)
341 execution.setVariable("nstSolution", nstSolution)
343 //set nst info into sliceTaskParams
344 SliceTaskParamsAdapter sliceTaskParams =
345 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
346 TemplateInfo nstInfo = new TemplateInfo()
347 nstInfo.setUUID(nstSolution.get("UUID") as String)
348 nstInfo.setInvariantUUID(nstSolution.get("invariantUUID") as String)
349 nstInfo.setName(nstSolution.get("name") as String)
351 sliceTaskParams.setNSTInfo(nstInfo)
353 execution.setVariable("sliceTaskParams", sliceTaskParams)
355 } catch (Exception ex) {
356 logger.debug( "Failed to get NST solution suggested by OOF.")
357 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
362 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
363 logger.debug("Start prepareUpdateOrchestrationTask")
364 String requestMethod = "PUT"
365 String taskStatus = execution.getVariable("taskStatus")
366 SliceTaskParamsAdapter sliceTaskParams =
367 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
368 String paramJson = sliceTaskParams.convertToJson()
369 execution.setVariable("CSSOT_status", taskStatus)
370 execution.setVariable("CSSOT_paramJson", paramJson)
371 execution.setVariable("CSSOT_requestMethod", requestMethod)
372 logger.debug("Finish prepareUpdateOrchestrationTask")
376 public void prepareGetUserOptions(DelegateExecution execution) {
377 logger.debug("Start prepareGetUserOptions")
378 String requestMethod = "GET"
379 execution.setVariable("taskAction", "commit")
380 String taskAction = execution.getVariable("taskAction")
381 logger.debug("task action is: " + taskAction)
382 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
383 String msg = "Unknown task action: " + taskAction
385 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
387 execution.setVariable("CSSOT_requestMethod", requestMethod)
388 logger.debug("Finish prepareGetUserOptions")
391 public void processUserOptions(DelegateExecution execution) {
392 logger.debug("Start processUserOptions")
393 String response = execution.getVariable("CSSOT_dbResponse")
394 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
395 String paramJson = orchestrationTask.getParams()
396 logger.debug("paramJson: " + paramJson)
397 SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
398 sliceTaskParams.convertFromJson(paramJson)
399 execution.setVariable("sliceTaskParams", sliceTaskParams)
400 logger.debug("Finish processUserOptions")
403 public void updateAAIOrchStatus(DelegateExecution execution) {
404 logger.debug("Start updateAAIOrchStatus")
405 String serviceInstanceId = execution.getVariable("serviceInstanceId")
406 String orchStatus = execution.getVariable("orchestrationStatus")
409 ServiceInstance si = new ServiceInstance()
410 si.setOrchestrationStatus(orchStatus)
412 AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
413 client.update(uri, si)
414 } catch (BpmnError e) {
416 } catch (Exception ex) {
417 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
419 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
422 logger.debug("Finish updateAAIOrchStatus")
425 public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
426 logger.debug("Start preUpdateServiceOperationStatus")
428 String serviceId = execution.getVariable("serviceInstanceId")
429 String operationId = execution.getVariable("operationId")
430 String operationType = execution.getVariable("operationType")
431 String userId = execution.getVariable("globalSubscriberId")
432 String result = execution.getVariable("operationResult")
433 String progress = execution.getVariable("operationProgress")
434 String reason = execution.getVariable("operationReason")
435 String operationContent = "service: " + result + " progress: " + progress
438 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
439 xmlns:ns="http://org.onap.so/requestsdb">
442 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
443 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
444 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
445 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
446 <userId>${MsoUtils.xmlEscape(userId)}</userId>
447 <result>${MsoUtils.xmlEscape(result)}</result>
448 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
449 <progress>${MsoUtils.xmlEscape(progress)}</progress>
450 <reason>${MsoUtils.xmlEscape(reason)}</reason>
451 </ns:initServiceOperationStatus>
453 </soapenv:Envelope>"""
455 payload = utils.formatXml(payload)
456 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
457 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
460 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
461 "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
462 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
464 logger.debug("Finish preUpdateServiceOperationStatus")
469 public void prepareCompletionRequest (DelegateExecution execution) {
470 logger.trace("Start prepareCompletionRequest")
472 String requestId = execution.getVariable("msoRequestId")
473 String serviceInstanceId = execution.getVariable("serviceInstanceId")
474 String source = execution.getVariable("source")
476 String msoCompletionRequest =
477 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
478 xmlns:ns="http://org.onap/so/request/types/v1">
479 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
480 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
481 <action>CREATE</action>
482 <source>${MsoUtils.xmlEscape(source)}</source>
484 <status-message>Service Instance was created successfully.</status-message>
485 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
486 <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
487 </aetgt:MsoCompletionRequest>"""
490 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
492 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
493 logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
495 } catch (Exception ex) {
496 String msg = " Exception in prepareCompletion:" + ex.getMessage()
498 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
500 logger.trace("Finish prepareCompletionRequest")