342fce75a521844f19084d273561521c1c019cb5
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2020, CMCC Technologies Co., Ltd.
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
10  #
11  #       http://www.apache.org/licenses/LICENSE-2.0
12  #
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=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.scripts
22
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import org.onap.aai.domain.yang.ServiceInstance
25 import org.onap.aaiclient.client.aai.AAIObjectType
26 import org.onap.aaiclient.client.aai.AAIResourcesClient
27 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
28 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
29 import org.onap.so.beans.nsmf.EsrInfo
30 import org.onap.so.beans.nsmf.NssmfAdapterNBIRequest
31 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
32 import org.onap.so.beans.nsmf.oof.TemplateInfo
33 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
34 import org.onap.so.bpmn.core.domain.ServiceDecomposition
35
36 import static org.apache.commons.lang3.StringUtils.*
37 import org.springframework.web.util.UriUtils
38 import groovy.json.JsonSlurper
39 import org.camunda.bpm.engine.delegate.BpmnError
40 import org.camunda.bpm.engine.delegate.DelegateExecution
41 import org.onap.so.beans.nsmf.SliceTaskParams
42 import org.onap.so.db.request.beans.OrchestrationTask
43 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
44 import org.onap.so.bpmn.common.scripts.ExceptionUtil
45 import org.onap.so.bpmn.common.scripts.OofUtils
46 import org.onap.so.bpmn.core.UrnPropertiesReader
47 import org.onap.so.bpmn.common.scripts.MsoUtils
48 import org.onap.so.bpmn.core.json.JsonUtils
49 import org.onap.logging.filter.base.ErrorCode
50 import org.onap.so.logger.LoggingAnchor
51 import org.onap.so.logger.MessageEnum
52 import org.slf4j.Logger
53 import org.slf4j.LoggerFactory
54
55 public class CreateSliceService extends AbstractServiceTaskProcessor {
56     String Prefix = "CRESS_"
57
58     ExceptionUtil exceptionUtil = new ExceptionUtil()
59     JsonUtils jsonUtil = new JsonUtils()
60     JsonSlurper jsonSlurper = new JsonSlurper()
61     ObjectMapper objectMapper = new ObjectMapper()
62     OofUtils oofUtils = new OofUtils()
63     NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
64     AAIResourcesClient client = getAAIClient()
65
66     private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
67
68     public void preProcessRequest(DelegateExecution execution) {
69         logger.debug("Start preProcessRequest")
70         execution.setVariable("prefix", Prefix)
71         String msg = ""
72
73         try {
74             String ssRequest = execution.getVariable("bpmnRequest")
75             logger.debug(ssRequest)
76
77             String requestId = execution.getVariable("mso-request-id")
78             execution.setVariable("msoRequestId", requestId)
79             logger.debug("Input Request:" + ssRequest + " reqId:" + requestId)
80
81             String serviceInstanceId = execution.getVariable("serviceInstanceId")
82             if (isBlank(serviceInstanceId)) {
83                 serviceInstanceId = UUID.randomUUID().toString()
84             }
85
86             String operationId = UUID.randomUUID().toString()
87             execution.setVariable("operationId", operationId)
88
89             logger.debug("Generated new Service Instance:" + serviceInstanceId)
90             serviceInstanceId = UriUtils.encode(serviceInstanceId, "UTF-8")
91             execution.setVariable("serviceInstanceId", serviceInstanceId)
92
93             //subscriberInfo
94             String globalSubscriberId = jsonUtil.getJsonValue(ssRequest, "requestDetails.subscriberInfo.globalSubscriberId")
95             if (isBlank(globalSubscriberId)) {
96                 msg = "Input globalSubscriberId' is null"
97                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
98             } else {
99                 execution.setVariable("globalSubscriberId", globalSubscriberId)
100             }
101
102             //requestInfo
103             execution.setVariable("source", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.source"))
104             execution.setVariable("serviceInstanceName", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.instanceName"))
105             execution.setVariable("disableRollback", jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.suppressRollback"))
106             String productFamilyId = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestInfo.productFamilyId")
107             if (isBlank(productFamilyId)) {
108                 msg = "Input productFamilyId is null"
109                 logger.debug(msg)
110                 //exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
111             } else {
112                 execution.setVariable("productFamilyId", productFamilyId)
113             }
114
115             //modelInfo
116             String serviceModelInfo = jsonUtil.getJsonValue(ssRequest, "requestDetails.modelInfo")
117             if (isBlank(serviceModelInfo)) {
118                 msg = "Input serviceModelInfo is null"
119                 logger.debug(msg)
120                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
121             } else {
122                 execution.setVariable("serviceModelInfo", serviceModelInfo)
123             }
124
125             logger.debug("modelInfo: " + serviceModelInfo)
126
127             //requestParameters
128             String subscriptionServiceType = jsonUtil.getJsonValue(ssRequest, "requestDetails.requestParameters.subscriptionServiceType")
129             if (isBlank(subscriptionServiceType)) {
130                 msg = "Input subscriptionServiceType is null"
131                 logger.debug(msg)
132                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
133             } else {
134                 execution.setVariable("subscriptionServiceType", subscriptionServiceType)
135             }
136             logger.debug("subscriptionServiceType: " + subscriptionServiceType)
137
138             /*
139             * Extracting User Parameters from incoming Request and converting into a Map
140             */
141             Map reqMap = jsonSlurper.parseText(ssRequest)
142
143             //InputParams
144             def userParamsList = reqMap.requestDetails?.requestParameters?.userParams
145
146             Map<String, String> inputMap = [:]
147             if (userParamsList) {
148                 for (def i = 0; i < userParamsList.size(); i++) {
149                     def userParams1 = userParamsList.get(i)
150                     userParams1.each { param -> inputMap.put(param.key, param.value) }
151                 }
152             }
153
154             logger.debug("User Input Parameters map: " + inputMap.toString())
155             String uuiRequest = inputMap.get("UUIRequest")
156             Map uuiReqMap = jsonSlurper.parseText(uuiRequest) as Map
157             Map<String, Object> serviceObject = (Map<String, Object>) uuiReqMap.get("service")
158             Map<String, Object> parameterObject = (Map<String, Object>) serviceObject.get("parameters")
159             Map<String, Object> requestInputs = (Map<String, Object>) parameterObject.get("requestInputs")
160
161             def serviceProfile = [:]
162             for(entry in requestInputs) {
163                 serviceProfile[entry.key] = entry.value
164             }
165
166             execution.setVariable("serviceInputParams", inputMap)
167             execution.setVariable("uuiRequest", uuiRequest)
168             execution.setVariable("se" +
169                     "rviceProfile", serviceProfile)
170
171             //TODO
172             //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
173             //execution.setVariable("failExists", true)
174
175         } catch (BpmnError e) {
176             throw e
177         } catch (Exception ex) {
178             msg = "Exception in preProcessRequest " + ex.getMessage()
179             logger.debug(msg)
180             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
181         }
182         logger.debug("Finish preProcessRequest")
183     }
184
185     /**
186      *
187      * @param execution
188      */
189     public void prepareInitServiceOperationStatus(DelegateExecution execution) {
190         logger.debug("Start prepareInitServiceOperationStatus")
191         try{
192             String serviceId = execution.getVariable("serviceInstanceId")
193             String operationId = execution.getVariable("operationId")
194             String operationType = "CREATE"
195             String userId = execution.getVariable("globalSubscriberId")
196             String result = "processing"
197             String progress = "0"
198             String reason = ""
199             String operationContent = "Prepare service creation"
200             logger.debug("Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId)
201             serviceId = UriUtils.encode(serviceId,"UTF-8")
202             execution.setVariable("serviceInstanceId", serviceId)
203             execution.setVariable("operationType", operationType)
204
205             def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint",execution)
206             execution.setVariable("CSSOS_dbAdapterEndpoint", dbAdapterEndpoint)
207             logger.debug("DB Adapter Endpoint is: " + dbAdapterEndpoint)
208             def dbAdapterAuth = UrnPropertiesReader.getVariable("mso.requestDb.auth")
209             Map<String, String> CSSOS_headerMap = [:]
210             CSSOS_headerMap.put("content-type", "application/soap+xml")
211             CSSOS_headerMap.put("Authorization", dbAdapterAuth)
212             execution.setVariable("CSSOS_headerMap", CSSOS_headerMap)
213             logger.debug("DB Adapter Header is: " + CSSOS_headerMap)
214
215             String payload =
216                     """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
217                         xmlns:ns="http://org.onap.so/requestsdb">
218                         <soapenv:Header/>
219                         <soapenv:Body>
220                             <ns:initServiceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
221                             <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
222                             <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
223                             <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
224                             <userId>${MsoUtils.xmlEscape(userId)}</userId>
225                             <result>${MsoUtils.xmlEscape(result)}</result>
226                             <operationContent>${MsoUtils.xmlEscape(operationContent)}</operationContent>
227                             <progress>${MsoUtils.xmlEscape(progress)}</progress>
228                             <reason>${MsoUtils.xmlEscape(reason)}</reason>
229                         </ns:initServiceOperationStatus>
230                     </soapenv:Body>
231                 </soapenv:Envelope>"""
232
233             payload = utils.formatXml(payload)
234             execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
235             logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
236         }catch(Exception e){
237             logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
238                     "Exception Occured Processing prepareInitServiceOperationStatus.", "BPMN",
239                     ErrorCode.UnknownError.getValue(), "Exception is:\n" + e)
240         }
241         logger.debug("Finish prepareInitServiceOperationStatus")
242     }
243
244     /**
245      * prepare create OrchestrationTask
246      * @param execution
247      */
248     public void prepareCreateOrchestrationTask(DelegateExecution execution) {
249         logger.debug("Start createOrchestrationTask")
250         String taskId = execution.getBusinessKey()
251         execution.setVariable("orchestrationTaskId", taskId)
252         logger.debug("BusinessKey: " + taskId)
253         String serviceInstanceId = execution.getVariable("serviceInstanceId")
254         String serviceInstanceName = execution.getVariable("serviceInstanceName")
255         String taskName = "SliceServiceTask"
256         String taskStatus = "Planning"
257         String isManual = "false"
258         String requestMethod = "POST"
259         execution.setVariable("CSSOT_taskId", taskId)
260         execution.setVariable("CSSOT_name", taskName)
261         execution.setVariable("CSSOT_status", taskStatus)
262         execution.setVariable("CSSOT_isManual", isManual)
263         execution.setVariable("CSSOT_requestMethod", requestMethod)
264
265         Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
266
267         SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
268         sliceTaskParams.setServiceId(serviceInstanceId)
269         sliceTaskParams.setServiceName(serviceInstanceName)
270         sliceTaskParams.setServiceProfile(serviceProfile)
271
272         execution.setVariable("sliceTaskParams", sliceTaskParams)
273
274         //todo:----------------------------------------
275 //        String paramJson = sliceTaskParams.convertToJson()
276 //        execution.setVariable("CSSOT_paramJson", paramJson)
277         /*-------------------------------------------*/
278
279         logger.debug("Finish createOrchestrationTask")
280     }
281
282     /**
283      *  send sync response to csmf
284      * @param execution
285      */
286     public void sendSyncResponse(DelegateExecution execution) {
287         logger.debug("Start sendSyncResponse")
288         try {
289             String operationId = execution.getVariable("operationId")
290             String serviceInstanceId = execution.getVariable("serviceInstanceId")
291             // RESTResponse for API Handler (APIH) Reply Task
292             String createServiceRestRequest = """
293                 {
294                    "service": {
295                         "serviceId":"${serviceInstanceId}",
296                         "operationId":"${operationId}"
297                    }
298                 }
299                 """.trim()
300
301             logger.debug("sendSyncResponse to APIH:" + "\n" + createServiceRestRequest)
302             sendWorkflowResponse(execution, 202, createServiceRestRequest)
303             execution.setVariable("sentSyncResponse", true)
304         } catch (Exception e) {
305             String msg = "Exceptuion in sendSyncResponse:" + e.getMessage()
306             logger.debug(msg)
307             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
308         }
309         logger.debug("Finish sendSyncResponse")
310     }
311
312     public void prepareSelectNSTRequest(DelegateExecution execution) {
313         logger.debug("Start prepareSelectNSTRequest")
314         String requestId = execution.getVariable("msoRequestId")
315         String messageType = "NSTSelectionResponse"
316         Map<String, Object> serviceProfile = execution.getVariable("serviceProfile") as Map<String, Object>
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)
322         String oofRequest = oofUtils.buildSelectNSTRequest(requestId, messageType, serviceProfile)
323         execution.setVariable("nstSelection_oofRequest", oofRequest)
324         logger.debug("Finish prepareSelectNSTRequest")
325
326     }
327
328     /**
329      * process async response of oof, put the {@solutions} at {@nstSolution}
330      * @param execution
331      */
332     public void processNSTSolutions(DelegateExecution execution) {
333         Map<String, Object> nstSolution
334         try {
335             logger.debug("Start processing NSTSolutions")
336             Map<String, Object> resMap =
337                     objectMapper.readValue(execution.getVariable("nstSelection_oofResponse") as String,
338                             Map.class)
339
340             List<Map<String, Object>> nstSolutions = (List<Map<String, Object>>) resMap.get("solutions")
341             nstSolution = nstSolutions.get(0)
342             execution.setVariable("nstSolution", nstSolution)
343
344             //set nst info into sliceTaskParams
345             SliceTaskParamsAdapter sliceTaskParams =
346                     execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
347             TemplateInfo nstInfo = new TemplateInfo()
348             nstInfo.setUUID(nstSolution.get("UUID") as String)
349             nstInfo.setInvariantUUID(nstSolution.get("invariantUUID") as String)
350             nstInfo.setName(nstSolution.get("name") as String)
351
352             sliceTaskParams.setNSTInfo(nstInfo)
353
354             execution.setVariable("sliceTaskParams", sliceTaskParams)
355
356         } catch (Exception ex) {
357             logger.debug( "Failed to get NST solution suggested by OOF.")
358             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Failed to get NST solution suggested by OOF.")
359         }
360
361     }
362
363     public void prepareUpdateOrchestrationTask(DelegateExecution execution) {
364         logger.debug("Start prepareUpdateOrchestrationTask")
365         String requestMethod = "PUT"
366         String taskStatus = execution.getVariable("taskStatus")
367         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
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")
373     }
374
375
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
384             logger.debug(msg)
385             exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
386         }
387         execution.setVariable("CSSOT_requestMethod", requestMethod)
388         logger.debug("Finish prepareGetUserOptions")
389     }
390
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         SliceTaskParams sliceTaskParams = new SliceTaskParams()
398         sliceTaskParams.convertFromJson(paramJson)
399         execution.setVariable("sliceTaskParams", sliceTaskParams)
400         logger.debug("Finish processUserOptions")
401     }
402
403     public void updateAAIOrchStatus(DelegateExecution execution) {
404         logger.debug("Start updateAAIOrchStatus")
405         String serviceInstanceId = execution.getVariable("serviceInstanceId")
406         String orchStatus = execution.getVariable("orchestrationStatus")
407
408         try {
409             ServiceInstance si = new ServiceInstance()
410             si.setOrchestrationStatus(orchStatus)
411             AAIResourcesClient client = new AAIResourcesClient()
412             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
413             client.update(uri, si)
414         } catch (BpmnError e) {
415             throw e
416         } catch (Exception ex) {
417             String msg = "Exception in CreateSliceService.updateAAIOrchStatus " + ex.getMessage()
418             logger.info(msg)
419             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
420         }
421
422         logger.debug("Finish updateAAIOrchStatus")
423     }
424
425     public void prepareUpdateServiceOperationStatus(DelegateExecution execution) {
426         logger.debug("Start preUpdateServiceOperationStatus")
427         try{
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
436
437             String payload =
438                     """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
439                         xmlns:ns="http://org.onap.so/requestsdb">
440                         <soapenv:Header/>
441                         <soapenv:Body>
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>
452                     </soapenv:Body>
453                 </soapenv:Envelope>"""
454
455             payload = utils.formatXml(payload)
456             execution.setVariable("CSSOS_updateServiceOperStatusRequest", payload)
457             logger.debug("Outgoing updateServiceOperStatusRequest: \n" + payload)
458
459         }catch(Exception e){
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())
463         }
464         logger.debug("Finish preUpdateServiceOperationStatus")
465     }
466
467
468
469     public void prepareCompletionRequest (DelegateExecution execution) {
470         logger.trace("Start prepareCompletionRequest")
471         try {
472             String requestId = execution.getVariable("msoRequestId")
473             String serviceInstanceId = execution.getVariable("serviceInstanceId")
474             String source = execution.getVariable("source")
475
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>
483                         </request-info>
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>"""
488
489             // Format Response
490             String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
491
492             execution.setVariable("completionRequest", xmlMsoCompletionRequest)
493             logger.debug("Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
494
495         } catch (Exception ex) {
496             String msg = " Exception in prepareCompletion:" + ex.getMessage()
497             logger.debug(msg)
498             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
499         }
500         logger.trace("Finish prepareCompletionRequest")
501     }
502
503 }
504