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.logging.filter.base.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 def serviceProfile = [:]
159 for(entry in requestInputs) {
160 serviceProfile[entry.key] = entry.value
163 execution.setVariable("serviceInputParams", inputMap)
164 execution.setVariable("uuiRequest", uuiRequest)
165 execution.setVariable("serviceProfile", 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")
181 public void getNSTSelection(DelegateExecution execution) {
182 logger.debug("Start getNSTSelection")
183 String requestId = execution.getVariable("msoRequestId")
184 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
185 String oofUrl = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
188 String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
189 String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
191 String basicAuthValue = utils.encrypt(basicAuth, msokey)
192 if (basicAuthValue != null) {
193 logger.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
195 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
196 execution.setVariable("BasicAuthHeaderValue", authHeader)
197 } catch (Exception ex) {
198 logger.debug( "Unable to encode username and password string: " + ex)
199 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
200 "encode username and password string")
203 logger.debug( "Unable to obtain BasicAuth - BasicAuth value null")
204 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
208 URL requestUrl = new URL(oofUrl + "/api/oof/v1/selection/nst")
209 String oofRequest = oofUtils.buildSelectNSTRequest(requestId, serviceProfile)
210 HttpClient httpClient = new HttpClientFactory().newJsonClient(requestUrl, ONAPComponents.OOF)
211 httpClient.addAdditionalHeader("Authorization", authHeader)
212 Response httpResponse = httpClient.post(oofRequest)
214 int responseCode = httpResponse.getStatus()
215 logger.debug("OOF sync response code is: " + responseCode)
217 if(responseCode != 200){
218 exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
221 Map<String, Object> nstSolution
223 Map<String, Object> resMap = httpResponse.readEntity(Map.class)
224 List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
225 nstSolution = nstSolutions.get(0)
226 execution.setVariable("nstSolution", nstSolution)
227 } catch (Exception ex) {
228 logger.debug( "Failed to get NST solution suggested by OOF.")
229 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
232 logger.debug("Finish getNSTSelection")
236 public void prepareDecomposeService(DelegateExecution execution) {
237 logger.debug("Start prepareDecomposeService")
238 String uuiRequest = execution.getVariable("uuiRequest")
239 String ssModelInvariantUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceInvariantUuid")
240 String ssModelUuid = jsonUtil.getJsonValue(uuiRequest, "service.serviceUuid")
241 String ssServiceModelInfo = """{
242 "modelInvariantUuid":"${ssModelInvariantUuid}",
243 "modelUuid":"${ssModelUuid}",
246 execution.setVariable("ssServiceModelInfo", ssServiceModelInfo)
248 logger.debug("Finish prepareDecomposeService")
251 public void processDecomposition(DelegateExecution execution) {
252 logger.debug("Start processDecomposition")
253 String uuiRequest = execution.getVariable("uuiRequest")
254 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
255 Map<String, Object> nstSolution = execution.getVariable("nstSolution")
257 Map uuiReqMap = jsonSlurper.parseText(uuiRequest)
258 Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
259 String subscriptionServiceType = serviceObject.get("serviceType")
261 String serviceType = (String) serviceProfile.get("sST")
262 String resourceSharingLevel = (String) serviceProfile.get("resourceSharingLevel")
263 String nstModelUuid = (String) nstSolution.get("UUID")
264 String nstModelInvariantUuid = (String) nstSolution.get("invariantUUID")
266 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
267 execution.setVariable("serviceType", serviceType)
268 execution.setVariable("resourceSharingLevel", resourceSharingLevel)
269 execution.setVariable("nstModelUuid", nstModelUuid)
270 execution.setVariable("nstModelInvariantUuid", nstModelInvariantUuid)
272 logger.debug("Finish processDecomposition")
275 public void prepareCreateOrchestrationTask(DelegateExecution execution) {
276 logger.debug("Start createOrchestrationTask")
277 String taskId = execution.getBusinessKey()
278 execution.setVariable("orchestrationTaskId", taskId)
279 logger.debug("BusinessKey: " + taskId)
280 String serviceInstanceId = execution.getVariable("serviceInstanceId")
281 String serviceInstanceName = execution.getVariable("serviceInstanceName")
282 String taskName = "SliceServiceTask"
283 String taskStatus = "Planning"
284 String isManual = "false"
285 String requestMethod = "POST"
286 execution.setVariable("CSSOT_taskId", taskId)
287 execution.setVariable("CSSOT_name", taskName)
288 execution.setVariable("CSSOT_status", taskStatus)
289 execution.setVariable("CSSOT_isManual", isManual)
290 execution.setVariable("CSSOT_requestMethod", requestMethod)
292 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
294 SliceTaskParams sliceTaskParams = new SliceTaskParams()
295 sliceTaskParams.setServiceId(serviceInstanceId)
296 sliceTaskParams.setServiceName(serviceInstanceName)
297 sliceTaskParams.setServiceProfile(serviceProfile)
298 execution.setVariable("sliceTaskParams", sliceTaskParams)
300 String paramJson = sliceTaskParams.convertToJson()
301 execution.setVariable("CSSOT_paramJson", paramJson)
302 logger.debug("CSSOT_paramJson: " + paramJson)
304 logger.debug("Finish createOrchestrationTask")
307 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
308 logger.debug("Start prepareUpdateOrchestrationTask")
309 String requestMethod = "PUT"
310 String taskStatus = execution.getVariable("taskStatus")
311 SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
312 String paramJson = sliceTaskParams.convertToJson()
313 execution.setVariable("CSSOT_status", taskStatus)
314 execution.setVariable("CSSOT_paramJson", paramJson)
315 execution.setVariable("CSSOT_requestMethod", requestMethod)
316 logger.debug("Finish prepareUpdateOrchestrationTask")
319 public void prepareGetUserOptions(DelegateExecution execution) {
320 logger.debug("Start prepareGetUserOptions")
321 String requestMethod = "GET"
322 execution.setVariable("taskAction", "commit")
323 String taskAction = execution.getVariable("taskAction")
324 logger.debug("task action is: " + taskAction)
325 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
326 String msg = "Unknown task action: " + taskAction
328 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
330 execution.setVariable("CSSOT_requestMethod", requestMethod)
331 logger.debug("Finish prepareGetUserOptions")
334 public void processUserOptions(DelegateExecution execution) {
335 logger.debug("Start processUserOptions")
336 String response = execution.getVariable("CSSOT_dbResponse")
337 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
338 String paramJson = orchestrationTask.getParams()
339 logger.debug("paramJson: " + paramJson)
340 SliceTaskParams sliceTaskParams = new SliceTaskParams()
341 sliceTaskParams.convertFromJson(paramJson)
342 execution.setVariable("sliceTaskParams", sliceTaskParams)
343 logger.debug("Finish processUserOptions")
346 public void updateAAIOrchStatus(DelegateExecution execution) {
347 logger.debug("Start updateAAIOrchStatus")
348 String serviceInstanceId = execution.getVariable("serviceInstanceId")
349 String orchStatus = execution.getVariable("orchestrationStatus")
352 ServiceInstance si = execution.getVariable("serviceInstanceData")
353 si.setOrchestrationStatus(orchStatus)
354 AAIResourcesClient client = new AAIResourcesClient()
355 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
356 client.update(uri, si)
357 } catch (BpmnError e) {
359 } catch (Exception ex) {
360 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
362 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
365 logger.debug("Finish updateAAIOrchStatus")
368 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
369 logger.debug("Start prepareInitServiceOperationStatus")
371 String serviceId = execution.getVariable("serviceInstanceId")
372 String operationId = execution.getVariable("operationId")
373 String operationType = "CREATE"
374 String userId = execution.getVariable("globalSubscriberId")
375 String result = "processing"
376 String progress = "0"
378 String operationContent = "Prepare service creation"
379 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
380 serviceId = UriUtils.encode(serviceId,"UTF-8")
381 execution.setVariable("serviceInstanceId", serviceId)
382 execution.setVariable("operationType", operationType)
384 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
385 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
386 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
387 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
388 Map<String, String> CSSOS_headerMap = [:]
389 CSSOS_headerMap.put("content-type", "application/soap+xml")
390 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
391 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
392 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
395 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
396 xmlns:ns="http://org.onap.so/requestsdb">
399 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
400 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
401 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
402 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
403 <userId>${MsoUtils.xmlEscape(userId)}</userId>
404 <result>${MsoUtils.xmlEscape(result)}</result>
405 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
406 <progress>${MsoUtils.xmlEscape(progress)}</progress>
407 <reason>${MsoUtils.xmlEscape(reason)}</reason>
408 </ns:initServiceOperationStatus>
410 </soapenv:Envelope>"""
412 payload = utils.formatXml(payload)
413 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
414 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
416 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
417 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
418 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
420 logger.debug("Finish prepareInitServiceOperationStatus")
423 public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
424 logger.debug("Start preUpdateServiceOperationStatus")
426 String serviceId = execution.getVariable("serviceInstanceId")
427 String operationId = execution.getVariable("operationId")
428 String operationType = execution.getVariable("operationType")
429 String userId = execution.getVariable("globalSubscriberId")
430 String result = execution.getVariable("operationResult")
431 String progress = execution.getVariable("operationProgress")
432 String reason = execution.getVariable("operationReason")
433 String operationContent = "service: " + result + " progress: " + progress
436 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
437 xmlns:ns="http://org.onap.so/requestsdb">
440 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
441 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
442 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
443 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
444 <userId>${MsoUtils.xmlEscape(userId)}</userId>
445 <result>${MsoUtils.xmlEscape(result)}</result>
446 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
447 <progress>${MsoUtils.xmlEscape(progress)}</progress>
448 <reason>${MsoUtils.xmlEscape(reason)}</reason>
449 </ns:initServiceOperationStatus>
451 </soapenv:Envelope>"""
453 payload = utils.formatXml(payload)
454 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
455 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
458 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
459 "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
460 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
462 logger.debug("Finish preUpdateServiceOperationStatus")
465 public void sendSyncResponse(DelegateExecution execution) {
466 logger.debug("Start sendSyncResponse")
468 String operationId = execution.getVariable("operationId")
469 String serviceInstanceId = execution.getVariable("serviceInstanceId")
470 // RESTResponse for API Handler (APIH) Reply Task
471 String createServiceRestRequest = """{"service":{"serviceId":"${serviceInstanceId}","operationId":"${operationId}"}}""".trim()
472 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
473 sendWorkflowResponse(execution, 202, createServiceRestRequest)
474 execution.setVariable("sentSyncResponse", true)
475 } catch (Exception e) {
476 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
478 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
480 logger.debug("Finish sendSyncResponse")
483 public void prepareCompletionRequest (DelegateExecution execution) {
484 logger.trace("Start prepareCompletionRequest")
486 String requestId = execution.getVariable("msoRequestId")
487 String serviceInstanceId = execution.getVariable("serviceInstanceId")
488 String source = execution.getVariable("source")
490 String msoCompletionRequest =
491 """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
492 xmlns:ns="http://org.onap/so/request/types/v1">
493 <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
494 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
495 <action>CREATE</action>
496 <source>${MsoUtils.xmlEscape(source)}</source>
498 <status-message>Service Instance was created successfully.</status-message>
499 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
500 <mso-bpel-name>CreateGenericALaCarteServiceInstance</mso-bpel-name>
501 </aetgt:MsoCompletionRequest>"""
504 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
506 execution.setVariable("completionRequest", xmlMsoCompletionRequest)
507 logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
509 } catch (Exception ex) {
510 String msg = " Exception in prepareCompletion:" + ex.getMessage()
512 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
514 logger.trace("Finish prepareCompletionRequest")