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