1dfe13738e3f606ffd5f7cd2cca0f676738061a3
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.scripts
24
25 import org.onap.so.logger.LoggingAnchor
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor;
29 import org.onap.so.bpmn.common.scripts.ExceptionUtil;
30 import org.onap.so.bpmn.common.scripts.MsoUtils
31 import org.onap.so.bpmn.core.WorkflowException
32 import org.onap.aaiclient.client.aai.AAIObjectType
33 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
34 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
35 import org.onap.logging.filter.base.ErrorCode
36 import org.onap.so.logger.MessageEnum
37 import org.slf4j.Logger
38 import org.slf4j.LoggerFactory
39
40 import groovy.json.JsonOutput
41 import groovy.json.JsonSlurper
42
43
44 class CreateVfModuleVolumeInfraV1 extends AbstractServiceTaskProcessor {
45         
46     private static final Logger logger = LoggerFactory.getLogger( CreateVfModuleVolumeInfraV1.class);
47         public static final String  prefix='CVMVINFRAV1_'
48
49         /**
50          * Perform initial processing, such as request validation, initialization of variables, etc.
51          * * @param execution
52          */
53         public void preProcessRequest (DelegateExecution execution) {
54                 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
55                 setBasicDBAuthHeader(execution, isDebugEnabled)
56                 preProcessRequest(execution, isDebugEnabled)
57         }
58
59
60         /**
61          * Perform initial processing, such as request validation, initialization of variables, etc.
62          * @param execution
63          * @param isDebugEnabled
64          */
65         public void preProcessRequest (DelegateExecution execution, isDebugEnabled) {
66
67                 execution.setVariable("prefix",prefix)
68                 setSuccessIndicator(execution, false)
69                 execution.setVariable(prefix+'syncResponseSent', false)
70
71                 String createVolumeIncoming = validateRequest(execution, 'vnfId')
72                 logger.debug(createVolumeIncoming)
73
74                 try {
75                         def jsonSlurper = new JsonSlurper()
76                         Map reqMap = jsonSlurper.parseText(createVolumeIncoming)
77                         setupVariables(execution, reqMap, isDebugEnabled)
78                         logger.debug("XML request:\n" + createVolumeIncoming)
79                 }
80                 catch(groovy.json.JsonException je) {
81                         (new ExceptionUtil()).buildAndThrowWorkflowException(execution, 2500, 'Request is not a valid JSON document')
82                 }
83
84                 // For rollback in this flow
85                 setBasicDBAuthHeader(execution, isDebugEnabled)
86                 setRollbackEnabled(execution, isDebugEnabled)
87         }
88
89         
90         /**
91          * Set up variables that will be passed to the BB DoCreatevfModuleVolume flow 
92          * @param execution
93          * @param requestMap
94          * @param serviceInstanceId
95          * @param isDebugLogEnabled
96          */
97         public void setupVariables(DelegateExecution execution, Map requestMap, isDebugLogEnabled) {
98                 
99                 def jsonOutput = new JsonOutput()
100                 
101                 // volumeGroupId - is generated
102                 String volumeGroupId = UUID.randomUUID()
103                 execution.setVariable('volumeGroupId', volumeGroupId)
104                 logger.debug("Generated volumeGroupId: " + volumeGroupId)
105                 
106                 // volumeGroupName
107                 def volGrpName = requestMap.requestDetails.requestInfo?.instanceName ?: ''
108                 execution.setVariable('volumeGroupName', volGrpName)
109
110                 // vfModuleModelInfo
111                 def vfModuleModelInfo = jsonOutput.toJson(requestMap.requestDetails?.modelInfo)
112                 execution.setVariable('vfModuleModelInfo', vfModuleModelInfo)
113                 
114                 // lcpCloudRegonId
115                 def lcpCloudRegionId = requestMap.requestDetails.cloudConfiguration.lcpCloudRegionId
116                 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
117                 
118                 // cloudOwner
119                 def cloudOwner = requestMap.requestDetails.cloudConfiguration.cloudOwner
120                 execution.setVariable('cloudOwner', cloudOwner)
121                 
122                 // tenant
123                 def tenantId = requestMap.requestDetails.cloudConfiguration.tenantId
124                 execution.setVariable('tenantId', tenantId)
125                 
126                 // source
127                 def source = requestMap.requestDetails.requestInfo.source
128                 execution.setVariable(prefix+'source', source)
129                 
130                 // vnfType and asdcServiceModelVersion
131                 
132                 def serviceName = ''
133                 def asdcServiceModelVersion = ''
134                 def modelCustomizationName = ''
135                 
136                 def relatedInstanceList = requestMap.requestDetails.relatedInstanceList
137                 relatedInstanceList.each {
138                         if (it.relatedInstance.modelInfo?.modelType == 'service') {
139                                 serviceName = it.relatedInstance.modelInfo?.modelName
140                                 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
141                         }
142                         if (it.relatedInstance.modelInfo?.modelType == 'vnf') {
143                                 modelCustomizationName = it.relatedInstance.modelInfo?.modelCustomizationName
144                         }
145                 }
146                 
147                 def vnfType = serviceName + '/' + modelCustomizationName
148                 execution.setVariable('vnfType', vnfType)
149                 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
150                 
151                 // vfModuleInputParams
152                 def userParams = requestMap.requestDetails?.requestParameters?.userParams
153                 Map<String, String> vfModuleInputMap = [:]
154                 
155                 userParams.each { userParam ->
156                         vfModuleInputMap.put(userParam.name, userParam.value.toString())
157                 }
158                 execution.setVariable('vfModuleInputParams', vfModuleInputMap)
159
160                 // disableRollback (true or false)
161                 def disableRollback = requestMap.requestDetails.requestInfo.suppressRollback
162                 execution.setVariable('disableRollback', disableRollback)
163                 logger.debug('disableRollback (suppressRollback) from request: ' + disableRollback)
164                 
165         }
166
167         
168         
169         public void sendSyncResponse (DelegateExecution execution, isDebugEnabled) {
170                 def volumeGroupId = execution.getVariable('volumeGroupId')
171                 def requestId = execution.getVariable("mso-request-id")
172                 def serviceInstanceId = execution.getVariable("serviceInstanceId")
173
174                 String syncResponse = """{"requestReferences":{"instanceId":"${volumeGroupId}","requestId":"${requestId}"}}""".trim()
175
176                 logger.debug("Sync Response: " + "\n" + syncResponse)
177                 sendWorkflowResponse(execution, 200, syncResponse)
178
179                 execution.setVariable(prefix+'syncResponseSent', true)
180         }
181
182
183         public void sendSyncError (DelegateExecution execution, isDebugEnabled) {
184                 WorkflowException we = execution.getVariable('WorkflowException')
185                 def errorCode = we?.getErrorCode()
186                 def errorMessage = we?.getErrorMessage()
187                 //default to 400 since only invalid request will trigger this method
188                 sendWorkflowResponse(execution, 400, errorMessage)
189         }
190
191
192         /**
193          * Create a WorkflowException
194          * @param execution
195          * @param isDebugEnabled
196          */
197         public void buildWorkflowException(DelegateExecution execution, int errorCode, errorMessage, isDebugEnabled) {
198                 logger.debug(errorMessage)
199                 (new ExceptionUtil()).buildWorkflowException(execution, 2500, errorMessage)
200         }
201
202
203         /**
204          * Build Infra DB Request
205          * @param execution
206          * @param isDebugEnabled
207          */
208         public void prepareDbInfraSuccessRequest(DelegateExecution execution, isDebugEnabled) {
209                 def dbVnfOutputs = execution.getVariable(prefix+'volumeOutputs')
210                 def requestId = execution.getVariable('mso-request-id')
211                 def statusMessage = "VolumeGroup successfully created."
212                 def requestStatus = "COMPLETED"
213                 def progress = "100"
214                 
215                 /*
216                 from: $gVolumeGroup/aai:volume-group-id/text()
217                 to: vnfreq:volume-outputs/vnfreq:volume-group-id
218                 */
219                 // for now assume, generated volumeGroupId is accepted
220                 def volumeGroupId = execution.getVariable(prefix+'volumeGroupId')
221
222                 String dbRequest =
223                         """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
224                                 <soapenv:Header/>
225                                 <soapenv:Body>
226                                         <ns:updateInfraRequest xmlns:ns="http://org.onap.so/requestsdb">
227                                                 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
228                                                 <lastModifiedBy>BPMN</lastModifiedBy>
229                                                 <statusMessage>${MsoUtils.xmlEscape(statusMessage)}</statusMessage>
230                                                 <responseBody></responseBody>
231                                                 <requestStatus>${MsoUtils.xmlEscape(requestStatus)}</requestStatus>
232                                                 <progress>${MsoUtils.xmlEscape(progress)}</progress>
233                                                 <vnfOutputs>${MsoUtils.xmlEscape(dbVnfOutputs)}</vnfOutputs>
234                                                 <volumeGroupId>${MsoUtils.xmlEscape(volumeGroupId)}</volumeGroupId>
235                                         </ns:updateInfraRequest>
236                                 </soapenv:Body>
237                            </soapenv:Envelope>"""
238
239                 String buildDBRequestAsString = utils.formatXml(dbRequest)
240                 execution.setVariable(prefix+"createDBRequest", buildDBRequestAsString)
241                 logger.debug("DB Infra Request: " + buildDBRequestAsString)
242         }
243
244
245         /**
246          * Build CommpleteMsoProcess request
247          * @param execution
248          * @param isDebugEnabled
249          */
250         public void postProcessResponse (DelegateExecution execution, isDebugEnabled) {
251
252                 def dbReturnCode = execution.getVariable(prefix+'dbReturnCode')
253                 def createDBResponse =  execution.getVariable(prefix+'createDBResponse')
254
255                 logger.debug('DB return code: ' + dbReturnCode)
256                 logger.debug('DB response: ' + createDBResponse)
257
258                 def requestId = execution.getVariable("mso-request-id")
259                 def source = execution.getVariable(prefix+'source')
260
261                 String msoCompletionRequest =
262                         """<aetgt:MsoCompletionRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
263                                                         xmlns:ns="http://org.onap/so/request/types/v1">
264                                         <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
265                                                 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
266                                                 <action>CREATE</action>
267                                                 <source>${MsoUtils.xmlEscape(source)}</source>
268                                         </request-info>
269                                         <aetgt:status-message>Volume Group has been created successfully.</aetgt:status-message>
270                                         <aetgt:mso-bpel-name>BPMN VF Module Volume action: CREATE</aetgt:mso-bpel-name>
271                                 </aetgt:MsoCompletionRequest>"""
272
273                 String xmlMsoCompletionRequest = utils.formatXml(msoCompletionRequest)
274
275                 execution.setVariable(prefix+'Success', true)
276                 execution.setVariable(prefix+'CompleteMsoProcessRequest', xmlMsoCompletionRequest)
277                 logger.debug(" Overall SUCCESS Response going to CompleteMsoProcess - " + "\n" + xmlMsoCompletionRequest)
278
279         }
280
281         public void prepareFalloutHandlerRequest(DelegateExecution execution, isDebugEnabled) {
282
283                 WorkflowException we = execution.getVariable('WorkflowException')
284                 def errorCode = we?.getErrorCode()
285                 def errorMessage = we?.getErrorMessage()
286
287                 def requestId = execution.getVariable("mso-request-id")
288                 def source = execution.getVariable(prefix+'source')
289
290                 String falloutHandlerRequest =
291                         """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
292                                                              xmlns:ns="http://org.onap/so/request/types/v1"
293                                                              xmlns:wfsch="http://org.onap/so/workflow/schema/v1">
294                                    <request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
295                                       <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
296                                       <action>CREATE</action>
297                                       <source>${MsoUtils.xmlEscape(source)}</source>
298                                    </request-info>
299                                            <aetgt:WorkflowException>
300                                               <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
301                                               <aetgt:ErrorCode>${MsoUtils.xmlEscape(errorCode)}</aetgt:ErrorCode>
302                                                 </aetgt:WorkflowException>
303
304                                 </aetgt:FalloutHandlerRequest>"""
305
306                 // Format Response
307                 String xmlHandlerRequest = utils.formatXml(falloutHandlerRequest)
308
309                 execution.setVariable(prefix+'FalloutHandlerRequest', xmlHandlerRequest)
310                 logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), "Overall Error Response " +
311                                 "going to FalloutHandler", "BPMN", ErrorCode.UnknownError.getValue(), "\n" + xmlHandlerRequest);
312         }
313
314
315         /**
316          * Query AAI service instance
317          * @param execution
318          * @param isDebugEnabled
319          */
320         public void callRESTQueryAAIServiceInstance(DelegateExecution execution, isDebugEnabled) {
321
322                 def request = execution.getVariable(prefix+"Request")
323                 def serviceInstanceId = utils.getNodeText(request, "service-instance-id")
324                 ExceptionUtil exceptionUtil = new ExceptionUtil()
325                 try {
326
327                         AAIResourceUri uri = AAIUriFactory.createNodesUri(AAIObjectType.SERVICE_INSTANCE,serviceInstanceId)
328                         if(getAAIClient().exists(uri)){
329                                 logger.debug('Service instance ' + serviceInstanceId + ' found in AAI.')
330                         }else{
331                                 def message = 'Service instance ' + serviceInstanceId + ' was not found in AAI. Return code: 404.'
332                                 logger.debug(message)
333                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, message)
334                         }
335                 }catch(BpmnError bpmnError){
336                         throw bpmnError
337                 }catch(Exception ex){
338                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, ex.getMessage())
339                 }
340         }
341         
342         public void logAndSaveOriginalException(DelegateExecution execution, isDebugLogEnabled) {
343                 logWorkflowException(execution, 'CreateVfModuleVolumeInfraV1 caught an event')
344                 saveWorkflowException(execution, 'CVMVINFRAV1_originalWorkflowException')
345         }
346         
347         public void validateRollbackResponse(DelegateExecution execution, isDebugLogEnabled) {
348
349                 def originalException = execution.getVariable("CVMVINFRAV1_originalWorkflowException")
350                 execution.setVariable("WorkflowException", originalException)
351                 execution.setVariable("RollbackCompleted", true)
352
353         }
354 }