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
24 import org.onap.so.serviceinstancebeans.Service
26 import static org.apache.commons.lang3.StringUtils.*
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.logging.filter.base.ErrorCode
35 import org.onap.so.beans.nsmf.SliceTaskParams
36 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
37 import org.onap.so.beans.nsmf.oof.TemplateInfo
38 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
39 import org.onap.so.bpmn.common.scripts.ExceptionUtil
40 import org.onap.so.bpmn.common.scripts.MsoUtils
41 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
42 import org.onap.so.bpmn.common.scripts.OofUtils
43 import org.onap.so.bpmn.core.UrnPropertiesReader
44 import org.onap.so.bpmn.core.json.JsonUtils
45 import org.onap.so.db.request.beans.OrchestrationTask
46 import org.onap.so.logger.LoggingAnchor
47 import org.onap.so.logger.MessageEnum
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
50 import org.springframework.web.util.UriUtils
51 import com.fasterxml.jackson.databind.ObjectMapper
52 import groovy.json.JsonSlurper
54 public class CreateSliceService extends AbstractServiceTaskProcessor {
55 String Prefix = "CRESS_"
57 ExceptionUtil exceptionUtil = new ExceptionUtil()
59 JsonUtils jsonUtil = new JsonUtils()
61 JsonSlurper jsonSlurper = new JsonSlurper()
63 ObjectMapper objectMapper = new ObjectMapper()
65 OofUtils oofUtils = new OofUtils()
67 AAIResourcesClient client = getAAIClient()
69 private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
71 public void preProcessRequest(DelegateExecution execution) {
72 logger.debug("Start preProcessRequest")
73 execution.setVariable("prefix", Prefix)
77 String ssRequest = execution.getVariable("bpmnRequest")
78 logger.debug(ssRequest)
80 String requestId = execution.getVariable("mso-request-id")
81 execution.setVariable("msoRequestId", requestId)
82 logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
84 String serviceInstanceId = execution.getVariable("serviceInstanceId")
85 if (isBlank(serviceInstanceId)) {
86 serviceInstanceId = UUID.randomUUID().toString()
89 String operationId = UUID.randomUUID().toString()
90 execution.setVariable("operationId", operationId)
92 logger.debug("Generated new Service Instance:" + serviceInstanceId)
93 serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
94 execution.setVariable("serviceInstanceId", serviceInstanceId)
97 String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
98 if (isBlank(globalSubscriberId)) {
99 msg = "Input globalSubscriberId' is null"
100 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
102 execution.setVariable("globalSubscriberId", globalSubscriberId)
106 execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
107 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
108 execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
109 String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
110 if (isBlank(productFamilyId)) {
111 msg = "Input productFamilyId is null"
113 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
115 execution.setVariable("productFamilyId", productFamilyId)
119 String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
120 if (isBlank(serviceModelInfo)) {
121 msg = "Input serviceModelInfo is null"
123 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
125 execution.setVariable("serviceModelInfo", serviceModelInfo)
128 logger.debug("modelInfo: " + serviceModelInfo)
130 // //requestParameters
131 // String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
132 // if (isBlank(subscriptionServiceType)) {
133 // msg = "Input subscriptionServiceType is null"
135 // exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
137 // subscriptionServiceType = "5G"
138 // execution.setVariable("subscriptionServiceType", subscriptionServiceType)
140 // logger.debug("subscriptionServiceType: " + subscriptionServiceType)
143 * Extracting User Parameters from incoming Request and converting into a Map
145 Map reqMap = jsonSlurper.parseText(ssRequest) as Map
148 def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
150 Map<String, String> inputMap = [:]
151 if (userParamsList) {
152 for (def i = 0; i < userParamsList.size(); i++) {
153 def userParams1 = userParamsList.get(i)
154 userParams1.each { param -> inputMap.put(param.key, param.value) }
158 logger.debug("User Input Parameters map: " + inputMap.toString())
159 String uuiRequest = inputMap.get("UUIRequest")
160 Map uuiReqMap = jsonSlurper.parseText(uuiRequest) as Map
161 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
162 Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
163 Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
165 def serviceProfile = [:]
166 for(entry in requestInputs) {
167 serviceProfile[entry.key] = entry.value
170 execution.setVariable("serviceInputParams", inputMap)
171 execution.setVariable("uuiRequest", uuiRequest)
172 execution.setVariable("serviceProfile", serviceProfile)
173 execution.setVariable("subscriptionServiceType", serviceObject.get("serviceType"))
176 //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
177 //execution.setVariable("failExists", true)
179 } catch (BpmnError e) {
181 } catch (Exception ex) {
182 msg = "Exception in preProcessRequest " + ex.getMessage()
184 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
186 logger.debug("Finish preProcessRequest")
193 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
194 logger.debug("Start prepareInitServiceOperationStatus")
196 String serviceId = execution.getVariable("serviceInstanceId")
197 String operationId = execution.getVariable("operationId")
198 String operationType = "CREATE"
199 String userId = execution.getVariable("globalSubscriberId")
200 String result = "processing"
201 String progress = "0"
203 String operationContent = "Prepare service creation"
204 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
205 serviceId = UriUtils.encode(serviceId,"UTF-8")
206 execution.setVariable("serviceInstanceId", serviceId)
207 execution.setVariable("operationType", operationType)
209 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
210 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
211 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
212 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
213 Map<String, String> CSSOS_headerMap = [:]
214 CSSOS_headerMap.put("content-type", "application/soap+xml")
215 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
216 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
217 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
220 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
221 xmlns:ns="http://org.onap.so/requestsdb">
224 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
225 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
226 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
227 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
228 <userId>${MsoUtils.xmlEscape(userId)}</userId>
229 <result>${MsoUtils.xmlEscape(result)}</result>
230 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
231 <progress>${MsoUtils.xmlEscape(progress)}</progress>
232 <reason>${MsoUtils.xmlEscape(reason)}</reason>
233 </ns:initServiceOperationStatus>
235 </soapenv:Envelope>"""
237 payload = utils.formatXml(payload)
238 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
239 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
241 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
242 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
243 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
245 logger.debug("Finish prepareInitServiceOperationStatus")
249 * prepare create OrchestrationTask
252 public void prepareCreateOrchestrationTask(DelegateExecution execution) {
253 logger.debug("Start createOrchestrationTask")
254 String taskId = execution.getBusinessKey()
255 execution.setVariable("orchestrationTaskId", taskId)
256 logger.debug("BusinessKey: " + taskId)
257 String serviceInstanceId = execution.getVariable("serviceInstanceId")
258 String serviceInstanceName = execution.getVariable("serviceInstanceName")
259 String taskName = "SliceServiceTask"
260 String taskStatus = "Planning"
261 String isManual = "false"
262 String requestMethod = "POST"
263 execution.setVariable("CSSOT_taskId", taskId)
264 execution.setVariable("CSSOT_name", taskName)
265 execution.setVariable("CSSOT_status", taskStatus)
266 execution.setVariable("CSSOT_isManual", isManual)
267 execution.setVariable("CSSOT_requestMethod", requestMethod)
269 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
271 SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
272 sliceTaskParams.setServiceId(serviceInstanceId)
273 sliceTaskParams.setServiceName(serviceInstanceName)
274 sliceTaskParams.setServiceProfile(serviceProfile)
276 execution.setVariable("sliceTaskParams", sliceTaskParams)
278 execution.setVariable("CSSOT_paramJson", objectMapper.writeValueAsString(sliceTaskParams))
280 logger.debug("Finish createOrchestrationTask")
284 * send sync response to csmf
287 public void sendSyncResponse(DelegateExecution execution) {
288 logger.debug("Start sendSyncResponse")
290 String operationId = execution.getVariable("operationId")
291 String serviceInstanceId = execution.getVariable("serviceInstanceId")
292 // RESTResponse for API Handler (APIH) Reply Task
293 String createServiceRestRequest = """
296 "serviceId":"${serviceInstanceId}",
297 "operationId":"${operationId}"
302 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
303 sendWorkflowResponse(execution, 202, createServiceRestRequest)
304 execution.setVariable("sentSyncResponse", true)
305 } catch (Exception e) {
306 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
308 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
310 logger.debug("Finish sendSyncResponse")
313 public void prepareSelectNSTRequest(DelegateExecution execution) {
314 logger.debug("Start prepareSelectNSTRequest")
315 String requestId = execution.getVariable("msoRequestId")
316 String messageType = "NSTSelectionResponse"
317 execution.setVariable("nstSelectionUrl", "/api/oof/v1/selection/nst")
318 execution.setVariable("nstSelection_messageType", messageType)
319 execution.setVariable("nstSelection_correlator", requestId)
320 String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution);
321 execution.setVariable("nstSelection_timeout", timeout)
323 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
324 serviceProfile.remove("profileId")
325 String oofRequest = oofUtils.buildSelectNSTRequest(requestId, messageType, serviceProfile)
326 execution.setVariable("nstSelection_oofRequest", oofRequest)
327 logger.debug("Finish prepareSelectNSTRequest")
332 * process async response of oof, put the {@solutions} at {@nstSolution}
335 public void processNSTSolutions(DelegateExecution execution) {
336 Map<String, Object> nstSolution
338 logger.debug("Start processing NSTSolutions")
339 Map<String, Object> resMap =
340 objectMapper.readValue(execution.getVariable("nstSelection_oofResponse") as String,
343 List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
344 nstSolution = nstSolutions.get(0)
345 execution.setVariable("nstSolution", nstSolution)
347 //set nst info into sliceTaskParams
348 SliceTaskParamsAdapter sliceTaskParams =
349 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
350 TemplateInfo nstInfo = new TemplateInfo()
351 nstInfo.setUUID(nstSolution.get("UUID") as String)
352 nstInfo.setInvariantUUID(nstSolution.get("invariantUUID") as String)
353 nstInfo.setName(nstSolution.get("NSTName") as String)
355 sliceTaskParams.setNSTInfo(nstInfo)
356 sliceTaskParams.setNstId(nstSolution.get("UUID") as String)
357 sliceTaskParams.setNstName(nstSolution.get("NSTName") as String)
359 execution.setVariable("sliceTaskParams", sliceTaskParams)
361 } catch (Exception ex) {
362 logger.debug( "Failed to get NST solution suggested by OOF.")
363 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
368 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
369 logger.debug("Start prepareUpdateOrchestrationTask")
370 String requestMethod = "PUT"
371 String taskStatus = execution.getVariable("taskStatus")
372 SliceTaskParamsAdapter sliceTaskParams =
373 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
374 int nsstCount=execution.getVariable("nsstCount") as int
375 nsstCount=nsstCount+1
376 execution.setVariable("nsstCount", nsstCount)
377 execution.setVariable("CSSOT_status", taskStatus)
378 execution.setVariable("CSSOT_paramJson", objectMapper.writeValueAsString(sliceTaskParams))
379 execution.setVariable("CSSOT_requestMethod", requestMethod)
380 logger.debug("Finish prepareUpdateOrchestrationTask")
384 public void prepareGetUserOptions(DelegateExecution execution) {
385 logger.debug("Start prepareGetUserOptions")
386 String requestMethod = "GET"
387 execution.setVariable("taskAction", "commit")
388 String taskAction = execution.getVariable("taskAction")
389 logger.debug("task action is: " + taskAction)
390 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
391 String msg = "Unknown task action: " + taskAction
393 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
395 execution.setVariable("CSSOT_requestMethod", requestMethod)
396 logger.debug("Finish prepareGetUserOptions")
399 public void processUserOptions(DelegateExecution execution) {
400 logger.debug("Start processUserOptions")
401 String response = execution.getVariable("CSSOT_dbResponse")
402 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
403 String paramJson = orchestrationTask.getParams()
404 logger.debug("paramJson: " + paramJson)
406 SliceTaskParamsAdapter sliceTaskParams = objectMapper.readValue(paramJson, SliceTaskParamsAdapter.class)
408 execution.setVariable("sliceTaskParams", sliceTaskParams)
409 logger.debug("Finish processUserOptions")
412 public void updateAAIOrchStatus(DelegateExecution execution) {
413 logger.debug("Start updateAAIOrchStatus")
414 String serviceInstanceId = execution.getVariable("serviceInstanceId")
415 String orchStatus = execution.getVariable("orchestrationStatus")
418 ServiceInstance si = new ServiceInstance()
419 si.setOrchestrationStatus(orchStatus)
421 AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
422 client.update(uri, si)
423 } catch (BpmnError e) {
425 } catch (Exception ex) {
426 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
428 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
431 logger.debug("Finish updateAAIOrchStatus")
434 public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
435 logger.debug("Start preUpdateServiceOperationStatus")
437 String serviceId = execution.getVariable("serviceInstanceId")
438 String operationId = execution.getVariable("operationId")
439 String operationType = execution.getVariable("operationType")
440 String userId = execution.getVariable("globalSubscriberId")
441 String result = execution.getVariable("operationResult")
442 String progress = execution.getVariable("operationProgress")
443 String reason = execution.getVariable("operationReason")
444 String operationContent = "service: " + result + " progress: " + progress
447 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
448 xmlns:ns="http://org.onap.so/requestsdb">
451 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
452 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
453 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
454 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
455 <userId>${MsoUtils.xmlEscape(userId)}</userId>
456 <result>${MsoUtils.xmlEscape(result)}</result>
457 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
458 <progress>${MsoUtils.xmlEscape(progress)}</progress>
459 <reason>${MsoUtils.xmlEscape(reason)}</reason>
460 </ns:initServiceOperationStatus>
462 </soapenv:Envelope>"""
464 payload = utils.formatXml(payload)
465 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
466 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
469 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
470 "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
471 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
473 logger.debug("Finish preUpdateServiceOperationStatus")
478 public void prepareCompletionRequest (DelegateExecution execution) {
479 logger.trace("Start prepareCompletionRequest")
481 String requestId = execution.getVariable("msoRequestId")
482 String serviceInstanceId = execution.getVariable("serviceInstanceId")
483 String source = execution.getVariable("source")
485 String msoCompletionRequest =
486 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
487 xmlns:ns="http://org.onap/so/request/types/v1">
488 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
489 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
490 <action>CREATE</action>
491 <source>${MsoUtils.xmlEscape(source)}</source>
493 <status-message>Service Instance was created successfully.</status-message>
494 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
495 <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
496 </aetgt:MsoCompletionRequest>"""
499 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
501 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
502 logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
504 } catch (Exception ex) {
505 String msg = " Exception in prepareCompletion:" + ex.getMessage()
507 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
509 logger.trace("Finish prepareCompletionRequest")