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.aaiclient.client.aai.AAIObjectType
28 import org.onap.aaiclient.client.aai.AAIResourcesClient
29 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
30 import org.onap.aaiclient.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 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 serviceInstanceName = execution.getVariable("serviceInstanceName")
277 String taskName = "SliceServiceTask"
278 String taskStatus = "Planning"
279 String isManual = "false"
280 String requestMethod = "POST"
281 execution.setVariable("CSSOT_taskId", taskId)
282 execution.setVariable("CSSOT_name", taskName)
283 execution.setVariable("CSSOT_status", taskStatus)
284 execution.setVariable("CSSOT_isManual", isManual)
285 execution.setVariable("CSSOT_requestMethod", requestMethod)
287 Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
289 SliceTaskParams sliceTaskParams = new SliceTaskParams()
290 sliceTaskParams.setServiceId(serviceInstanceId)
291 sliceTaskParams.setServiceName(serviceInstanceName)
292 sliceTaskParams.setServiceProfile(serviceProfile)
293 execution.setVariable("sliceTaskParams", sliceTaskParams)
295 String paramJson = sliceTaskParams.convertToJson()
296 execution.setVariable("CSSOT_paramJson", paramJson)
297 logger.debug("CSSOT_paramJson: " + paramJson)
299 logger.debug("Finish createOrchestrationTask")
302 public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
303 logger.debug("Start prepareUpdateOrchestrationTask")
304 String requestMethod = "PUT"
305 String taskStatus = execution.getVariable("taskStatus")
306 SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
307 String paramJson = sliceTaskParams.convertToJson()
308 execution.setVariable("CSSOT_status", taskStatus)
309 execution.setVariable("CSSOT_paramJson", paramJson)
310 execution.setVariable("CSSOT_requestMethod", requestMethod)
311 logger.debug("Finish prepareUpdateOrchestrationTask")
314 public void prepareGetUserOptions(DelegateExecution execution) {
315 logger.debug("Start prepareGetUserOptions")
316 String requestMethod = "GET"
317 execution.setVariable("taskAction", "commit")
318 String taskAction = execution.getVariable("taskAction")
319 logger.debug("task action is: " + taskAction)
320 if (!"commit".equals(taskAction) && !"abort".equals(taskAction)) {
321 String msg = "Unknown task action: " + taskAction
323 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
325 execution.setVariable("CSSOT_requestMethod", requestMethod)
326 logger.debug("Finish prepareGetUserOptions")
329 public void processUserOptions(DelegateExecution execution) {
330 logger.debug("Start processUserOptions")
331 String response = execution.getVariable("CSSOT_dbResponse")
332 OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
333 String paramJson = orchestrationTask.getParams()
334 logger.debug("paramJson: " + paramJson)
335 SliceTaskParams sliceTaskParams = new SliceTaskParams()
336 sliceTaskParams.convertFromJson(paramJson)
337 execution.setVariable("sliceTaskParams", sliceTaskParams)
338 logger.debug("Finish processUserOptions")
341 public void updateAAIOrchStatus(DelegateExecution execution) {
342 logger.debug("Start updateAAIOrchStatus")
343 String serviceInstanceId = execution.getVariable("serviceInstanceId")
344 String orchStatus = execution.getVariable("orchestrationStatus")
347 ServiceInstance si = execution.getVariable("serviceInstanceData")
348 si.setOrchestrationStatus(orchStatus)
349 AAIResourcesClient client = new AAIResourcesClient()
350 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
351 client.update(uri, si)
352 } catch (BpmnError e) {
354 } catch (Exception ex) {
355 String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
357 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
360 logger.debug("Finish updateAAIOrchStatus")
363 public void prepareInitServiceOperationStatus(DelegateExecution execution) {
364 logger.debug("Start prepareInitServiceOperationStatus")
366 String serviceId = execution.getVariable("serviceInstanceId")
367 String operationId = execution.getVariable("operationId")
368 String operationType = "CREATE"
369 String userId = execution.getVariable("globalSubscriberId")
370 String result = "processing"
371 String progress = "0"
373 String operationContent = "Prepare service creation"
374 logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
375 serviceId = UriUtils.encode(serviceId,"UTF-8")
376 execution.setVariable("serviceInstanceId", serviceId)
377 execution.setVariable("operationType", operationType)
379 def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
380 execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
381 logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
382 def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
383 Map<String, String> CSSOS_headerMap = [:]
384 CSSOS_headerMap.put("content-type", "application/soap+xml")
385 CSSOS_headerMap.put("Authorization", dbAdapterAuth)
386 execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
387 logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
390 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
391 xmlns:ns="http://org.onap.so/requestsdb">
394 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
395 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
396 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
397 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
398 <userId>${MsoUtils.xmlEscape(userId)}</userId>
399 <result>${MsoUtils.xmlEscape(result)}</result>
400 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
401 <progress>${MsoUtils.xmlEscape(progress)}</progress>
402 <reason>${MsoUtils.xmlEscape(reason)}</reason>
403 </ns:initServiceOperationStatus>
405 </soapenv:Envelope>"""
407 payload = utils.formatXml(payload)
408 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
409 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
411 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
412 "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
413 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
415 logger.debug("Finish prepareInitServiceOperationStatus")
418 public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
419 logger.debug("Start preUpdateServiceOperationStatus")
421 String serviceId = execution.getVariable("serviceInstanceId")
422 String operationId = execution.getVariable("operationId")
423 String operationType = execution.getVariable("operationType")
424 String userId = execution.getVariable("globalSubscriberId")
425 String result = execution.getVariable("operationResult")
426 String progress = execution.getVariable("operationProgress")
427 String reason = execution.getVariable("operationReason")
428 String operationContent = "service: " + result + " progress: " + progress
431 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
432 xmlns:ns="http://org.onap.so/requestsdb">
435 <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
436 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
437 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
438 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
439 <userId>${MsoUtils.xmlEscape(userId)}</userId>
440 <result>${MsoUtils.xmlEscape(result)}</result>
441 <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
442 <progress>${MsoUtils.xmlEscape(progress)}</progress>
443 <reason>${MsoUtils.xmlEscape(reason)}</reason>
444 </ns:initServiceOperationStatus>
446 </soapenv:Envelope>"""
448 payload = utils.formatXml(payload)
449 execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
450 logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
453 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
454 "Exception Occured Processing preUpdateServiceOperationStatus.", "BPMN",
455 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e.getMessage())
457 logger.debug("Finish preUpdateServiceOperationStatus")
460 public void sendSyncResponse(DelegateExecution execution) {
461 logger.debug("Start sendSyncResponse")
463 String operationId = execution.getVariable("operationId")
464 String serviceInstanceId = execution.getVariable("serviceInstanceId")
465 // RESTResponse for API Handler (APIH) Reply Task
466 String createServiceRestRequest = """{"service":{"serviceId":"${serviceInstanceId}","operationId":"${operationId}"}}""".trim()
467 logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
468 sendWorkflowResponse(execution, 202, createServiceRestRequest)
469 execution.setVariable("sentSyncResponse", true)
470 } catch (Exception e) {
471 String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
473 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
475 logger.debug("Finish sendSyncResponse")
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")