[MSO-8] Update the maven dependency
[so.git] / bpmn / MSOInfrastructureBPMN / src / main / groovy / org / openecomp / mso / bpmn / infrastructure / scripts / UpdateVfModuleVolume.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
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.openecomp.mso.bpmn.infrastructure.scripts
22
23 import java.util.concurrent.ExecutionException;
24
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.runtime.Execution
27 import org.apache.commons.lang3.*
28 import org.springframework.web.util.UriUtils
29 import org.openecomp.mso.bpmn.common.scripts.AaiUtil
30 import org.openecomp.mso.bpmn.common.scripts.VfModuleBase
31 import org.openecomp.mso.bpmn.core.WorkflowException
32 import org.openecomp.mso.bpmn.core.json.JsonUtils;
33 import org.openecomp.mso.rest.APIResponse
34
35 class UpdateVfModuleVolume extends VfModuleBase {
36         
37         /**
38          * Initialize the flow's variables.
39          * 
40          * @param execution The flow's execution instance.
41          */
42         private void initProcessVariables(Execution execution) {
43                 execution.setVariable('prefix', 'UPDVfModVol_')
44                 execution.setVariable('UPDVfModVol_Request', null)
45                 execution.setVariable('UPDVfModVol_requestInfo', null)
46                 execution.setVariable('UPDVfModVol_requestId', null)
47                 execution.setVariable('UPDVfModVol_source', null)
48                 execution.setVariable('UPDVfModVol_volumeInputs', null)
49                 execution.setVariable('UPDVfModVol_volumeGroupId', null)
50                 execution.setVariable('UPDVfModVol_vnfType', null)
51                 execution.setVariable('UPDVfModVol_serviceId', null)
52                 execution.setVariable('UPDVfModVol_aicCloudRegion', null)
53                 execution.setVariable('UPDVfModVol_tenantId', null)
54                 execution.setVariable('UPDVfModVol_volumeParams', null)
55                 execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', null)
56                 execution.setVariable('UPDVfModVol_volumeGroupTenantId', null)
57                 execution.setVariable('UpdateVfModuleVolumeSuccessIndicator', false)
58         }
59         
60         /**
61          * Check for missing elements in the received request.
62          * 
63          * @param execution The flow's execution instance.
64          */
65         @Override
66         public void preProcessRequest(Execution execution) {
67                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
68                         'execution=' + execution.getId() +
69                         ')'
70                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
71                 logDebug('Entered ' + method, isDebugLogEnabled)
72                 
73                 try {
74                         initProcessVariables(execution)
75                         String request = validateRequest(execution)
76                         
77                         def requestInfo = getRequiredNodeXml(execution, request, 'request-info')
78                         execution.setVariable('UPDVfModVol_requestInfo', requestInfo)
79                         execution.setVariable('UPDVfModVol_requestId', getRequiredNodeText(execution, requestInfo, 'request-id'))
80                         execution.setVariable('UPDVfModVol_source', getNodeTextForce(requestInfo, 'source'))
81                         
82                         def volumeInputs = getRequiredNodeXml(execution, request, 'volume-inputs')
83                         execution.setVariable('UPDVfModVol_volumeInputs', volumeInputs)
84                         execution.setVariable('UPDVfModVol_volumeGroupId', getRequiredNodeText(execution, volumeInputs, 'volume-group-id'))
85                         execution.setVariable('UPDVfModVol_vnfType', getRequiredNodeText(execution, volumeInputs, 'vnf-type'))
86                         execution.setVariable('UPDVfModVol_serviceId', getRequiredNodeText(execution, volumeInputs, 'service-id'))
87                         execution.setVariable('UPDVfModVol_aicCloudRegion', getRequiredNodeText(execution, volumeInputs, 'aic-cloud-region'))
88                         execution.setVariable('UPDVfModVol_tenantId', getRequiredNodeText(execution, volumeInputs, 'tenant-id'))
89
90                         def volumeParams = utils.getNodeXml(request, 'volume-params')
91                         execution.setVariable('UPDVfModVol_volumeParams', volumeParams)
92
93                         logDebug('Exited ' + method, isDebugLogEnabled)
94                         utils.logAudit("UpdateVfModuleVolume request: " + request)
95                 } catch (BpmnError bpmnError) {
96                         throw bpmnError
97                 } catch (Exception e) {
98                         logError('Caught exception in ' + method, e)
99                         createWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
100                 }
101         }
102
103         /**
104          * Prepare and send the synchronous response.
105          * 
106          * @param execution The flow's execution instance.
107          */
108         public void sendSynchResponse(Execution execution) {
109                 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
110                         'execution=' + execution.getId() +
111                         ')'
112                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
113                 logDebug('Entered ' + method, isDebugLogEnabled)
114                 
115                 try {
116                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
117                         def requestId = execution.getVariable('UPDVfModVol_requestId')
118                         def source = execution.getVariable('UPDVfModVol_source')
119                         def progress = getNodeTextForce(requestInfo, 'progress')
120                         if (progress.isEmpty()) {
121                                 progress = '0'
122                         }
123                         def startTime = getNodeTextForce(requestInfo, 'start-time')
124                         if (startTime.isEmpty()) {
125                                 startTime = System.currentTimeMillis()
126                         }
127                         def volumeInputs = execution.getVariable('UPDVfModVol_volumeInputs')
128                         
129                         String synchResponse = """
130                                 <volume-request xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
131                                         <request-info>
132                                                 <request-id>${requestId}</request-id>
133                                                 <action>UPDATE_VF_MODULE_VOL</action>
134                                                 <request-status>IN_PROGRESS</request-status>
135                                                 <progress>${progress}</progress>
136                                                 <start-time>${startTime}</start-time>
137                                                 <source>${source}</source>
138                                         </request-info>
139                                         ${volumeInputs}
140                                 </volume-request>
141                         """
142
143                         synchResponse = utils.formatXml(synchResponse)
144                         sendWorkflowResponse(execution, 200, synchResponse)
145                         utils.logAudit("UpdateVfModuleVolume Synch Response: " + synchResponse)
146                 } catch (BpmnError e) {
147                         throw e;
148                 } catch (Exception e) {
149                         logError('Caught exception in ' + method, e)
150                         createWorkflowException(execution, 1002, 'Error in sendSynchResponse(): ' + e.getMessage())
151                 }               
152         }
153         
154         /**
155          * Prepare a Request for querying AAI for Volume Group information using the
156          * Volume Group Id and Aic Cloud Region.
157          * 
158          * @param execution The flow's execution instance.
159          */
160         public void queryAAIForVolumeGroup(Execution execution) {
161                 def method = getClass().getSimpleName() + '.queryAAIForVolumeGroup(' +
162                         'execution=' + execution.getId() +
163                         ')'
164                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
165                 logDebug('Entered ' + method, isDebugLogEnabled)
166
167                 try {
168                         def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
169                         def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
170                         def endPoint = execution.getVariable('URN_aai_endpoint') +
171                                 '/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/' + UriUtils.encode(aicCloudRegion, "UTF-8") +
172                                 '/volume-groups/volume-group/' + UriUtils.encode(volumeGroupId, "UTF-8")
173
174                         logDebug('Sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
175                         utils.logAudit("UpdateVfModuleVolume sending GET for quering AAI endpoint: " + endPoint)
176                         
177                         AaiUtil aaiUtil = new AaiUtil(this)
178                         APIResponse response = aaiUtil.executeAAIGetCall(execution, endPoint)
179                         def int statusCode = response.getStatusCode()
180                         def responseData = response.getResponseBodyAsString()
181                         logDebug('Response code:' + statusCode, isDebugLogEnabled)
182                         logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
183                         utils.logAudit("UpdateVfModuleVolume response data: " + responseData)
184                         
185                         def volumeGroup = responseData
186                         def heatStackId = getNodeTextForce(volumeGroup, 'heat-stack-id')
187                         execution.setVariable('UPDVfModVol_volumeGroupHeatStackId', heatStackId)
188                         if ((statusCode == 200) || (statusCode == 204)) {
189                                 def volumeGroupTenantId = getTenantIdFromVolumeGroup(volumeGroup)
190                                 if (volumeGroupTenantId == null) {
191                                         throw new Exception('Could not find Tenant Id element in Volume Group with Volume Group Id \'' + volumeGroupId + '\''
192                                                 + '\', AIC Cloud Region \'' + aicCloudRegion + '\'')
193                                 }
194                                 execution.setVariable('UPDVfModVol_volumeGroupTenantId', volumeGroupTenantId)
195                                 logDebug('Received Tenant Id \'' + volumeGroupTenantId + '\' from AAI for Volume Group with Volume Group Id \'' + volumeGroupId + '\''
196                                         + '\', AIC Cloud Region \'' + aicCloudRegion + '\'', isDebugLogEnabled)
197                         } else if (statusCode == 404) {
198                                 throw new Exception('Volume Group \'' + volumeGroupId + '\' not found at AAI')
199                         } else {
200                                 throw new Exception('Bad status code ' + statusCode + ' received from AAI; Response data: ' + responseData)
201                         }
202
203                         logDebug('Exited ' + method, isDebugLogEnabled)
204                 } catch (BpmnError e) {
205                         throw e;
206                 } catch (Exception e) {
207                         logError('Caught exception in ' + method, e)
208                         createWorkflowException(execution, 1002, 'Error in queryAAIForVolumeGroup(): ' + e.getMessage())
209                 }
210         }
211         
212         /**
213          * Prepare a Request for invoking the VnfAdapterRest subflow to do
214          * a Volume Group update.
215          *
216          * @param execution The flow's execution instance.
217          */
218         public void prepVnfAdapterRest(Execution execution) {
219                 def method = getClass().getSimpleName() + '.prepVnfAdapterRest(' +
220                         'execution=' + execution.getId() +
221                         ')'
222                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
223                 logDebug('Entered ' + method, isDebugLogEnabled)
224                 
225                 try {
226                         def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
227                         def tenantId = execution.getVariable('UPDVfModVol_tenantId')
228                         def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
229                         def volumeGroupHeatStackId = execution.getVariable('UPDVfModVol_volumeGroupHeatStackId')
230                         def vnfType = execution.getVariable('UPDVfModVol_vnfType')
231                         
232                         def volumeParamsXml = execution.getVariable('UPDVfModVol_volumeParams')
233                         def volumeGroupParams = transformParamsToEntries(volumeParamsXml)
234                         
235                         def requestId = execution.getVariable('UPDVfModVol_requestId')
236                         def serviceId = execution.getVariable('UPDVfModVol_serviceId')
237                         
238                         def messageId = execution.getVariable('mso-request-id') + '-' + System.currentTimeMillis()
239                         def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId) 
240                         def useQualifiedHostName = execution.getVariable("URN_mso_use_qualified_host")
241                         if ('true'.equals(useQualifiedHostName)) {
242                                         notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
243                         }
244
245                         String vnfAdapterRestRequest = """
246                                 <updateVolumeGroupRequest>
247                                         <cloudSiteId>${aicCloudRegion}</cloudSiteId>
248                                         <tenantId>${tenantId}</tenantId>
249                                         <volumeGroupId>${volumeGroupId}</volumeGroupId>
250                                         <volumeGroupStackId>${volumeGroupHeatStackId}</volumeGroupStackId>
251                                         <vnfType>${vnfType}</vnfType>
252                                         <vnfVersion></vnfVersion>
253                                         <vfModuleType></vfModuleType>
254                                         <volumeGroupParams>
255                                                 ${volumeGroupParams}
256                                     </volumeGroupParams>
257                                         <skipAAI>true</skipAAI>
258                                     <msoRequest>
259                                         <requestId>${requestId}</requestId>
260                                         <serviceInstanceId>${serviceId}</serviceInstanceId>
261                                     </msoRequest>
262                                     <messageId>${messageId}</messageId>
263                                     <notificationUrl>${notificationUrl}</notificationUrl>
264                                 </updateVolumeGroupRequest>
265                         """
266                         vnfAdapterRestRequest = utils.formatXml(vnfAdapterRestRequest)
267                         execution.setVariable('UPDVfModVol_vnfAdapterRestRequest', vnfAdapterRestRequest)
268                         logDebug('Request for VNFAdapter Rest:\n' + vnfAdapterRestRequest, isDebugLogEnabled)
269                         
270                         utils.logAudit("UpdateVfModuleVolume Request for VNFAdapter Rest: " + vnfAdapterRestRequest)
271                         logDebug('Exited ' + method, isDebugLogEnabled)
272                 } catch (BpmnError e) {
273                         throw e;
274                 } catch (Exception e) {
275                         logError('Caught exception in ' + method, e)
276                         createWorkflowException(execution, 1002, 'Error in prepVnfAdapterRest(): ' + e.getMessage())
277                 }
278         }
279         
280         /**
281          * Prepare a Request for updating the DB for this Infra request.
282          *
283          * @param execution The flow's execution instance.
284          */
285         public void prepDbInfraDbRequest(Execution execution) {
286                 def method = getClass().getSimpleName() + '.prepDbInfraDbRequest(' +
287                         'execution=' + execution.getId() +
288                         ')'
289                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
290                 logDebug('Entered ' + method, isDebugLogEnabled)
291
292                 try {
293                         def requestId = execution.getVariable('UPDVfMod_requestId')
294                         
295                         String updateInfraRequest = """
296                                 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
297                                                 xmlns:req="http://org.openecomp.mso/requestsdb">
298                                         <soapenv:Header/>
299                                         <soapenv:Body>
300                                                 <req:updateInfraRequest>
301                                                         <requestId>${requestId}</requestId>
302                                                         <lastModifiedBy>BPEL</lastModifiedBy>
303                                                         <requestStatus>COMPLETE</requestStatus>
304                                                         <progress>100</progress>
305                                                 </req:updateInfraRequest>
306                                         </soapenv:Body>
307                                 </soapenv:Envelope>
308                         """
309
310                         updateInfraRequest = utils.formatXml(updateInfraRequest)
311                         execution.setVariable('UPDVfModVol_updateInfraRequest', updateInfraRequest)
312                         logDebug('Request for Update Infra Request:\n' + updateInfraRequest, isDebugLogEnabled)
313                         
314                         utils.logAudit("UpdateVfModuleVolume Request for Updating DB for Infra: " + updateInfraRequest)
315                         logDebug('Exited ' + method, isDebugLogEnabled)
316                 } catch (BpmnError e) {
317                         throw e;
318                 } catch (Exception e) {
319                         logError('Caught exception in ' + method, e)
320                         createWorkflowException(execution, 1002, 'Error in prepDbInfraDbRequest(): ' + e.getMessage())
321                 }
322         }
323         
324         /**
325          * Build a "CompletionHandler" request.
326          * 
327          * @param execution The flow's execution instance.
328          */
329         public void prepCompletionHandlerRequest(Execution execution) {
330                 def method = getClass().getSimpleName() + '.prepCompletionHandlerRequest(' +
331                         'execution=' + execution.getId() +
332                         ')'
333                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
334                 logDebug('Entered ' + method, isDebugLogEnabled)
335                 
336                 try {
337                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
338
339                         String content = """
340                                 <sdncadapterworkflow:MsoCompletionRequest xmlns:sdncadapterworkflow="http://org.openecomp/mso/workflow/schema/v1"
341                                                 xmlns:reqtype="http://org.openecomp/mso/request/types/v1">
342                                         ${requestInfo}
343                                         <sdncadapterworkflow:mso-bpel-name>MSO_ACTIVATE_BPEL</sdncadapterworkflow:mso-bpel-name>
344                                 </sdncadapterworkflow:MsoCompletionRequest>
345                         """
346
347                         content = utils.formatXml(content)
348                         logDebug('Request for Completion Handler:\n' + content, isDebugLogEnabled)
349                         utils.logAudit("UpdateVfModuleVolume Completion Handler request: " + content)
350                         execution.setVariable('UPDVfModVol_CompletionHandlerRequest', content)
351                         
352                         logDebug('Exited ' + method, isDebugLogEnabled)
353                 } catch (BpmnError e) {
354                         throw e;
355                 } catch (Exception e) {
356                         logError('Caught exception in ' + method, e)
357                         createWorkflowException(execution, 1002, 'Error in prepCompletionHandlerRequest(): ' + e.getMessage())
358                 }
359         }
360         
361         /**
362          * Build a "FalloutHandler" request.
363          * 
364          * @param execution The flow's execution instance.
365          */
366         public void prepFalloutHandler(Execution execution) {
367                 def method = getClass().getSimpleName() + '.prepFalloutHandler(' +
368                         'execution=' + execution.getId() +
369                         ')'
370                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
371                 logDebug('Entered ' + method, isDebugLogEnabled)
372
373                 try {
374                         def requestInfo = execution.getVariable('UPDVfModVol_requestInfo')
375                         
376                         def WorkflowException workflowException = execution.getVariable("WorkflowException")
377                         def errorResponseCode = workflowException.getErrorCode()
378                         def errorResponseMsg = workflowException.getErrorMessage()
379                         def encErrorResponseMsg = ""
380                         if (errorResponseMsg != null) {
381                                 encErrorResponseMsg = errorResponseMsg.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
382                         }
383
384                         String content = """
385                                 <sdncadapterworkflow:FalloutHandlerRequest xmlns:sdncadapterworkflow="http://org.openecomp/mso/workflow/schema/v1"
386                                                 xmlns:reqtype="http://org.openecomp/mso/request/types/v1"
387                                                 xmlns:msoservtypes="http://org.openecomp/mso/request/types/v1"
388                                                 xmlns:structuredtypes="http://org.openecomp/mso/structured/types/v1">
389                                         ${requestInfo}
390                                         <sdncadapterworkflow:WorkflowException>
391                                                 <sdncadapterworkflow:ErrorMessage>${encErrorResponseMsg}</sdncadapterworkflow:ErrorMessage>
392                                                 <sdncadapterworkflow:ErrorCode>${errorResponseCode}</sdncadapterworkflow:ErrorCode>
393                                         </sdncadapterworkflow:WorkflowException>        
394                                 </sdncadapterworkflow:FalloutHandlerRequest>
395                         """
396                         content = utils.formatXml(content)
397                         logDebug('Request for Fallout Handler:\n' + content, isDebugLogEnabled)
398                         utils.logAudit("UpdateVfModuleVolume Fallout request: " + content)
399                         execution.setVariable('UPDVfModVol_FalloutHandlerRequest', content)
400                         
401                         logDebug('Exited ' + method, isDebugLogEnabled)
402                 } catch (BpmnError e) {
403                         throw e;
404                 } catch (Exception e) {
405                         logError('Caught exception in ' + method, e)
406                         createWorkflowException(execution, 1002, 'Error in prepFalloutHandler(): ' + e.getMessage())
407                 }
408         }
409         
410         /**
411          * Create a WorkflowException for the error case where the Tenant Id from
412          * AAI did not match the Tenant Id in the incoming request.
413          * 
414          * @param execution The flow's execution instance.
415          */
416         public void handleTenantIdMismatch(Execution execution) {
417                 def method = getClass().getSimpleName() + '.handleTenantIdMismatch(' +
418                         'execution=' + execution.getId() +
419                         ')'
420                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
421                 logDebug('Entered ' + method, isDebugLogEnabled)
422                 
423                 String processKey = getProcessKey(execution);
424                 def volumeGroupId = execution.getVariable('UPDVfModVol_volumeGroupId')
425                 def aicCloudRegion = execution.getVariable('UPDVfModVol_aicCloudRegion')
426                 def tenantId = execution.getVariable('UPDVfModVol_tenantId')
427                 def volumeGroupTenantId = execution.getVariable('UPDVfModVol_volumeGroupTenantId')
428                 
429                 def String errorMessage = 'TenantId \'' + tenantId + '\' in incoming request does not match Tenant Id \'' + volumeGroupTenantId +
430                         '\' retrieved from AAI for Volume Group Id \'' + volumeGroupId + '\', AIC Cloud Region \'' + aicCloudRegion + '\''
431                         
432                 logError('Error in UpdateVfModuleVol: ' + errorMessage)
433                 
434                 WorkflowException exception = new WorkflowException(processKey, 5000, errorMessage);
435                 execution.setVariable("WorkflowException", exception);
436                 
437                 logDebug('Exited ' + method, isDebugLogEnabled)
438                 utils.logAudit("UpdateVfModuleVolume workflowException in Tenant Mismatch: " + errorMessage)
439         }
440 }