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