2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 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 org.onap.aai.domain.yang.ServiceInstance
25 import org.onap.so.client.HttpClient
26 import org.onap.so.client.HttpClientFactory
27 import org.onap.so.client.aai.AAIObjectType
28 import org.onap.so.client.aai.AAIResourcesClient
29 import org.onap.so.client.aai.entities.uri.AAIResourceUri
30 import org.onap.so.client.aai.entities.uri.AAIUriFactory
32 import javax.ws.rs.core.Response
34 import static org.apache.commons.lang3.StringUtils.*
35 import org.springframework.web.util.UriUtils
36 import groovy.json.JsonSlurper
37 import org.camunda.bpm.engine.delegate.BpmnError
38 import org.camunda.bpm.engine.delegate.DelegateExecution
39 import org.onap.logging.filter.base.ONAPComponents
40 import org.onap.so.beans.nsmf.SliceTaskParams
41 import org.onap.so.db.request.beans.OrchestrationTask
42 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
43 import org.onap.so.bpmn.common.scripts.ExceptionUtil
44 import org.onap.so.bpmn.common.scripts.OofUtils
45 import org.onap.so.bpmn.core.UrnPropertiesReader
46 import org.onap.so.bpmn.common.scripts.MsoUtils
47 import org.onap.so.bpmn.core.json.JsonUtils
48 import org.onap.so.logger.ErrorCode
49 import org.onap.so.logger.LoggingAnchor
50 import org.onap.so.logger.MessageEnum
51 import org.slf4j.Logger
52 import org.slf4j.LoggerFactory
54 public class CreateSliceService extends AbstractServiceTaskProcessor {
55 String Prefix = "CRESS_"
57 ExceptionUtil exceptionUtil = new ExceptionUtil()
58 JsonUtils jsonUtil = new JsonUtils()
59 JsonSlurper jsonSlurper = new JsonSlurper()
60 ObjectMapper objectMapper = new ObjectMapper()
61 OofUtils oofUtils = new OofUtils()
62 private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
65 public void preProcessRequest(DelegateExecution execution) {
66 logger.debug("Start preProcessRequest")
67 execution.setVariable("prefix", Prefix)
71 String ssRequest = execution.getVariable("bpmnRequest")
72 logger.debug(ssRequest)
74 String requestId = execution.getVariable("mso-request-id")
75 execution.setVariable("msoRequestId", requestId)
76 logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
78 String serviceInstanceId = execution.getVariable("serviceInstanceId")
79 if (isBlank(serviceInstanceId)) {
80 serviceInstanceId = UUID.randomUUID().toString()
83 String operationId = UUID.randomUUID().toString()
84 execution.setVariable("operationId", operationId)
86 logger.debug("Generated new Service Instance:" + serviceInstanceId)
87 serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
88 execution.setVariable("serviceInstanceId", serviceInstanceId)
91 String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
92 if (isBlank(globalSubscriberId)) {
93 msg = "Input globalSubscriberId' is null"
94 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
96 execution.setVariable("globalSubscriberId", globalSubscriberId)
100 execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
101 execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
102 execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
103 String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
104 if (isBlank(productFamilyId)) {
105 msg = "Input productFamilyId is null"
107 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
109 execution.setVariable("productFamilyId", productFamilyId)
113 String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
114 if (isBlank(serviceModelInfo)) {
115 msg = "Input serviceModelInfo is null"
117 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
119 execution.setVariable("serviceModelInfo", serviceModelInfo)
122 logger.debug("modelInfo: " + serviceModelInfo)
125 String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
126 if (isBlank(subscriptionServiceType)) {
127 msg = "Input subscriptionServiceType is null"
129 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
131 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
133 logger.debug("subscriptionServiceType: " + subscriptionServiceType)
136 * Extracting User Parameters from incoming Request and converting into a Map
138 Map reqMap = jsonSlurper.parseText(ssRequest)
141 def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
143 Map<String, String> inputMap = [:]
144 if (userParamsList) {
145 for (def i = 0; i < userParamsList.size(); i++) {
146 def userParams1 = userParamsList.get(i)
147 userParams1.each { param -> inputMap.put(param.key, param.value) }
151 logger.debug("User Input Parameters map: " + inputMap.toString())
152 String uuiRequest = inputMap.get("UUIRequest")
153 Map uuiReqMap = jsonSlurper.parseText(uuiRequest)
154 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
155 Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
156 Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
158 execution.setVariable("serviceInputParams", inputMap)
159 execution.setVariable("uuiRequest", uuiRequest)
160 execution.setVariable("serviceProfile", requestInputs)
163 //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
164 //execution.setVariable("failExists", true)
166 } catch (BpmnError e) {
168 } catch (Exception ex) {
169 msg = "Exception in preProcessRequest " + ex.getMessage()
171 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
173 logger.debug("Finish preProcessRequest")
176 public void getNSTSelection(DelegateExecution execution) {
177 logger.debug("Start getNSTSelection")
178 String requestId = execution.getVariable("msoRequestId")
179 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
180 String oofUrl = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
183 String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
184 String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
186 String basicAuthValue = utils.encrypt(basicAuth, msokey)
187 if (basicAuthValue != null) {
188 logger.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
190 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
191 execution.setVariable("BasicAuthHeaderValue", authHeader)
192 } catch (Exception ex) {
193 logger.debug( "Unable to encode username and password string: " + ex)
194 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
195 "encode username and password string")
198 logger.debug( "Unable to obtain BasicAuth - BasicAuth value null")
199 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
203 URL requestUrl = new URL(oofUrl + "/api/oof/v1/selection/nst")
204 String oofRequest = oofUtils.buildSelectNSTRequest(requestId, serviceProfile)
205 HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.OOF)
206 httpClient.addAdditionalHeader("Authorization", authHeader)
207 Response httpResponse = httpClient.post(oofRequest)
209 int responseCode = httpResponse.getStatus()
210 logger.debug("OOF sync response code is: " + responseCode)
212 if(responseCode != 200){
213 exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
216 Map<String, Object> nstSolution
218 Map<String, Object> resMap = httpResponse.readEntity(Map.class)
219 List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
220 nstSolution = nstSolutions.get(0)
221 execution.setVariable("nstSolution", nstSolution)
222 } catch (Exception ex) {
223 logger.debug( "Failed to get NST solution suggested by OOF.")
224 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
227 logger.debug("Finish getNSTSelection")
231 public void prepareDecomposeService(DelegateExecution execution) {
232 logger.debug("Start prepareDecomposeService")
233 String uuiRequest = execution.getVariable("uuiRequest")
234 String ssModelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid")
235 String ssModelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid")
236 String ssServiceModelInfo = """{
237 "modelInvariantUuid":"${ssModelInvariantUuid}",
238 "modelUuid":"${ssModelUuid}",
241 execution.setVariable("ssServiceModelInfo", ssServiceModelInfo)
243 logger.debug("Finish prepareDecomposeService")
246 public void processDecomposition(DelegateExecution execution) {
247 logger.debug("Start processDecomposition")
248 String uuiRequest = execution.getVariable("uuiRequest")
249 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
250 Map<String, Object> nstSolution = execution.getVariable("nstSolution")
252 Map uuiReqMap = jsonSlurper.parseText(uuiRequest)
253 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
254 String subscriptionServiceType = serviceObject.get("serviceType")
256 String serviceType = (String) serviceProfile.get("sST")
257 String resourceSharingLevel = (String) serviceProfile.get("resourceSharingLevel")
258 String nstModelUuid = (String) nstSolution.get("UUID")
259 String nstModelInvariantUuid = (String) nstSolution.get("invariantUUID")
261 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
262 execution.setVariable("serviceType", serviceType)
263 execution.setVariable("resourceSharingLevel", resourceSharingLevel)
264 execution.setVariable("nstModelUuid", nstModelUuid)
265 execution.setVariable("nstModelInvariantUuid", nstModelInvariantUuid)
267 logger.debug("Finish processDecomposition")
270 public void prepareCreateOrchestrationTask(DelegateExecution execution) {
271 logger.debug("Start createOrchestrationTask")
272 String taskId = execution.getBusinessKey()
273 execution.setVariable("orchestrationTaskId", taskId)
274 logger.debug("BusinessKey: " + taskId)
275 String serviceInstanceId = execution.getVariable("serviceInstanceId")
276 String operationId = execution.getVariable("operationId")
277 String serviceInstanceName = execution.getVariable("serviceInstanceName")
278 String taskName = "SliceServiceTask"
279 String taskStatus = "Planning"
280 String isManual = "false"
281 String requestMethod = "POST"
282 execution.setVariable("CSSOT_taskId", taskId)
283 execution.setVariable("CSSOT_name", taskName)
284 execution.setVariable("CSSOT_status", taskStatus)
285 execution.setVariable("CSSOT_isManual", isManual)
286 execution.setVariable("CSSOT_requestMethod", requestMethod)
288 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
289 Map<String, Object> sliceProfileTn = execution.getVariable("sliceProfileTn")
290 Map<String, Object> sliceProfileCn = execution.getVariable("sliceProfileCn")
291 Map<String, Object> sliceProfileAn = execution.getVariable("sliceProfileAn")
293 SliceTaskParams sliceTaskParams = new SliceTaskParams()
294 sliceTaskParams.setServiceId(serviceInstanceId)
295 sliceTaskParams.setServiceName(serviceInstanceName)
296 sliceTaskParams.setServiceProfile(serviceProfile)
297 sliceTaskParams.setSliceProfileTn(sliceProfileTn)
298 sliceTaskParams.setSliceProfileCn(sliceProfileCn)
299 sliceTaskParams.setSliceProfileAn(sliceProfileAn)
300 execution.setVariable("sliceTaskParams", sliceTaskParams)
302 String paramJson = sliceTaskParams.convertToJson()
303 execution.setVariable("CSSOT_paramJson", paramJson)
304 logger.debug("CSSOT_paramJson: " + paramJson)
306 logger.debug("Finish createOrchestrationTask")
309 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
310 logger.debug("Start prepareUpdateOrchestrationTask")
311 String requestMethod = "PUT"
312 String taskStatus = execution.getVariable("taskStatus")
313 SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
314 String paramJson = sliceTaskParams.convertToJson()
315 execution.setVariable("CSSOT_status", taskStatus)
316 execution.setVariable("CSSOT_paramJson", paramJson)
317 execution.setVariable("CSSOT_requestMethod", requestMethod)
318 logger.debug("Finish prepareUpdateOrchestrationTask")
321 public void prepareGetUserOptions(DelegateExecution execution) {
322 logger.debug("Start prepareGetUserOptions")
323 String requestMethod = "GET"
324 execution.setVariable("taskAction", "commit")
325 String taskAction = execution.getVariable("taskAction")
326 logger.debug("task action is: " + taskAction)
327 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
328 String msg = "Unknown task action: " + taskAction
330 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
332 execution.setVariable("CSSOT_requestMethod", requestMethod)
333 logger.debug("Finish prepareGetUserOptions")
336 public void processUserOptions(DelegateExecution execution) {
337 logger.debug("Start processUserOptions")
338 String response = execution.getVariable("CSSOT_dbResponse")
339 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
340 String paramJson = orchestrationTask.getParams()
341 logger.debug("paramJson: " + paramJson)
342 SliceTaskParams sliceTaskParams = new SliceTaskParams()
343 sliceTaskParams.convertFromJson(paramJson)
344 execution.setVariable("sliceTaskParams", sliceTaskParams)
345 logger.debug("Finish processUserOptions")
348 public void updateAAIOrchStatus(DelegateExecution execution) {
349 logger.debug("Start updateAAIOrchStatus")
350 String serviceInstanceId = execution.getVariable("serviceInstanceId")
351 String orchStatus = execution.getVariable("orchestrationStatus")
354 ServiceInstance si = execution.getVariable("serviceInstanceData")
355 si.setOrchestrationStatus(orchStatus)
356 AAIResourcesClient client = new AAIResourcesClient()
357 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
358 client.update(uri, si)
359 } catch (BpmnError e) {
361 } catch (Exception ex) {
362 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
364 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
367 logger.debug("Finish updateAAIOrchStatus")
370 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
371 logger.debug("Start prepareInitServiceOperationStatus")
373 String serviceId = execution.getVariable("serviceInstanceId")
374 String operationId = execution.getVariable("operationId")
375 String operationType = "CREATE"
376 String userId = execution.getVariable("globalSubscriberId")
377 String result = "processing"
378 String progress = "0"
380 String operationContent = "Prepare service creation"
381 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
382 serviceId = UriUtils.encode(serviceId,"UTF-8")
383 execution.setVariable("serviceInstanceId", serviceId)
384 execution.setVariable("operationType", operationType)
386 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
387 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
388 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
389 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
390 Map<String, String> CSSOS_headerMap = [:]
391 CSSOS_headerMap.put("content-type", "application/soap+xml")
392 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
393 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
394 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
397 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
398 xmlns:ns="http://org.onap.so/requestsdb">
401 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
402 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
403 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
404 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
405 <userId>${MsoUtils.xmlEscape(userId)}</userId>
406 <result>${MsoUtils.xmlEscape(result)}</result>
407 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
408 <progress>${MsoUtils.xmlEscape(progress)}</progress>
409 <reason>${MsoUtils.xmlEscape(reason)}</reason>
410 </ns:initServiceOperationStatus>
412 </soapenv:Envelope>"""
414 payload = utils.formatXml(payload)
415 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
416 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
418 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
419 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
420 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
422 logger.debug("Finish prepareInitServiceOperationStatus")
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")
467 public void sendSyncResponse(DelegateExecution execution) {
468 logger.debug("Start sendSyncResponse")
470 String operationId = execution.getVariable("operationId")
471 String serviceInstanceId = execution.getVariable("serviceInstanceId")
472 // RESTResponse for API Handler (APIH) Reply Task
473 String createServiceRestRequest = """{"service":{"serviceId":"${serviceInstanceId}","operationId":"${operationId}"}}""".trim()
474 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
475 sendWorkflowResponse(execution, 202, createServiceRestRequest)
476 execution.setVariable("sentSyncResponse", true)
477 } catch (Exception e) {
478 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
480 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
482 logger.debug("Finish sendSyncResponse")
485 public void prepareCompletionRequest (DelegateExecution execution) {
486 logger.trace("Start prepareCompletionRequest")
488 String requestId = execution.getVariable("msoRequestId")
489 String serviceInstanceId = execution.getVariable("serviceInstanceId")
490 String source = execution.getVariable("source")
492 String msoCompletionRequest =
493 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
494 xmlns:ns="http://org.onap/so/request/types/v1">
495 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
496 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
497 <action>CREATE</action>
498 <source>${MsoUtils.xmlEscape(source)}</source>
500 <status-message>Service Instance was created successfully.</status-message>
501 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
502 <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
503 </aetgt:MsoCompletionRequest>"""
506 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
508 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
509 logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
511 } catch (Exception ex) {
512 String msg = " Exception in prepareCompletion:" + ex.getMessage()
514 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
516 logger.trace("Finish prepareCompletionRequest")