Remove unnecessary use of Calendar.getInstance()
[so.git] / bpmn / MSOGammaBPMN / src / main / groovy / com / att / bpm / scripts / PrepareUpdateAAIVfModule.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 com.att.bpm.scripts
22
23 import groovy.util.Node
24 import groovy.xml.QName
25
26 import java.io.Serializable;
27
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.runtime.Execution
30 import org.springframework.web.util.UriUtils
31
32 import org.openecomp.mso.rest.APIResponse
33 import org.openecomp.mso.rest.RESTClient
34 import org.openecomp.mso.rest.RESTConfig
35 import org.openecomp.mso.bpmn.core.RollbackData
36 import org.openecomp.mso.bpmn.core.WorkflowException
37 import com.jayway.jsonpath.internal.Utils;
38
39 public class PrepareUpdateAAIVfModule extends VfModuleBase {
40         
41         /**
42          * Initialize the flow's variables.
43          * 
44          * @param execution The flow's execution instance.
45          */
46         public void initProcessVariables(Execution execution) {
47                 execution.setVariable('prefix', 'PUAAIVfMod_')
48                 execution.setVariable('PUAAIVfMod_vnfId', null)
49                 execution.setVariable('PUAAIVfMod_vfModuleId', null)
50                 execution.setVariable('PUAAIVfMod_vnfName', null)
51                 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
52                 execution.setVariable('PUAAIVfMod_vfModule', null)
53                 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
54                 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
55                 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
56                 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
57                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
58                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
59                 execution.setVariable('PUAAIVfMod_outVfModule', null)
60         }       
61         
62         /**
63          * Check for missing elements in the received request.
64          * 
65          * @param execution The flow's execution instance.
66          */
67         public void preProcessRequest(Execution execution) {
68                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
69                         'execution=' + execution.getId() +
70                         ')'
71                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
72                 logDebug('Entered ' + method, isDebugLogEnabled)
73
74                 try {
75                         def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
76                         logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
77                         initProcessVariables(execution)
78                         
79                         def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
80                         execution.setVariable('PUAAIVfMod_vnfId', vnfId)
81
82                         def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
83                         execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
84                         
85                         def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
86                         execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
87
88                         logDebug('Exited ' + method, isDebugLogEnabled)
89                 } catch (BpmnError e) {
90                         throw e;
91                 } catch (Exception e) {
92                         logError('Caught exception in ' + method, e)
93                         createWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
94                 }
95         }
96         
97         /**
98          * Using the received vnfId, query AAI to get the corresponding Generic VNF.
99          * A 200 response is expected with the Generic VNF in the response body.
100          * 
101          * @param execution The flow's execution instance.
102          */
103         public void getGenericVnf(Execution execution) {
104                 def method = getClass().getSimpleName() + '.getGenericVnf(' +
105                         'execution=' + execution.getId() +
106                         ')'
107                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
108                 logDebug('Entered ' + method, isDebugLogEnabled)
109
110                 try {
111                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
112                         
113                         AaiUtil aaiUriUtil = new AaiUtil(this)
114                         def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
115                         logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
116                         
117                         String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8")
118
119                         String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
120
121                         try {
122                                 RESTConfig config = new RESTConfig(endPoint);
123                                 def responseData = ''
124                                 def aaiRequestId = UUID.randomUUID().toString()
125                                 RESTClient client = new RESTClient(config).
126                                         addHeader('X-TransactionId', aaiRequestId).
127                                         addHeader('X-FromAppId', 'MSO').
128                                         addHeader('Content-Type', 'application/xml').
129                                         addHeader('Accept','application/xml');
130                                 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
131                                         client.addAuthorizationHeader(basicAuthCred)
132                                 }
133                                 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
134                                 APIResponse response = client.httpGet()
135                                         
136                                 responseData = response.getResponseBodyAsString()
137                                 execution.setVariable('PUAAIVfMod_getVnfResponseCode', response.getStatusCode())
138                                 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
139                                 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
140                                 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
141                         } catch (Exception ex) {
142                                 ex.printStackTrace()
143                                 logDebug('Exception occurred while executing AAI GET:' + ex.getMessage(), isDebugLogEnabled)
144                                 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
145                                 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
146                         }
147                         logDebug('Exited ' + method, isDebugLogEnabled)
148                 } catch (BpmnError e) {
149                         throw e;
150                 } catch (Exception e) {
151                         logError('Caught exception in ' + method, e)
152                         createWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
153                 }
154         }
155         
156         /**
157          * Validate the VF Module.  That is, confirm that a VF Module with the input VF Module ID
158          * exists in the retrieved Generic VNF.  Then, check to make sure that if that VF Module
159          * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
160          * attempting to delete it.
161          * 
162          * @param execution The flow's execution instance.
163          */
164         public void validateVfModule(Execution execution) {
165                 def method = getClass().getSimpleName() + '.validateVfModule(' +
166                         'execution=' + execution.getId() +
167                         ')'
168                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
169                 logDebug('Entered ' + method, isDebugLogEnabled)
170                 
171                 try {
172                         def genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
173                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
174                         def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
175                         def vnfName = getNodeTextForce(genericVnf, 'vnf-name')
176                         execution.setVariable('PUAAIVfMod_vnfName', vnfName)
177                         def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
178                         if (vfModule == null) {
179                                 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
180                                 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
181                                 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
182                         } else {
183                                 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
184                                 if (isDebugLogEnabled) {
185                                         logDebug('VF Module \'' + vfModuleId + '\': isBaseVfModule=' + vfModule.isBaseVfModule() +
186                                                 ', isOnlyVfModule=' + vfModule.isOnlyVfModule() + ', new orchestration-status=' + orchestrationStatus,
187                                                 isDebugLogEnabled)
188                                 }
189                                 if (vfModule.isBaseVfModule() && !vfModule.isOnlyVfModule() && orchestrationStatus.equals('pending-delete')) {
190                                         def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
191                                                 '\' cannot be set to \'pending-delete\' since it is the base VF Module and it\'s not the only VF Module in Generic VNF \'' + vnfId + '\''
192                                         execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
193                                         execution.setVariable('PUAAIVfMod_vfModuleOK', false)
194                                 } else {
195                                         execution.setVariable('PUAAIVfMod_vfModule', vfModule)
196                                         execution.setVariable('PUAAIVfMod_vfModuleOK', true)
197                                 }
198                         }
199                         
200                         logDebug('Exited ' + method, isDebugLogEnabled)
201                 } catch (BpmnError e) {
202                         throw e;
203                 } catch (Exception e) {
204                         logError('Caught exception in ' + method, e)
205                         createWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
206                 }
207         }
208         
209         /**
210          * Construct and send a PUT request to AAI to update the VF Module.
211          * 
212          * @param execution The flow's execution instance.
213          */
214         public void updateVfModule(Execution execution) {
215                 def method = getClass().getSimpleName() + '.updateVfModule(' +
216                         'execution=' + execution.getId() +
217                         ')'
218                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
219                 logDebug('Entered ' + method, isDebugLogEnabled)
220                 
221                 try {
222                         // Construct payload
223                         def VfModule vfModule = (VfModule) execution.getVariable('PUAAIVfMod_vfModule')
224                         def Node newVfModuleNode = vfModule.getNode().clone()
225                         def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
226                         def Node orchestrationStatusNode = utils.getChildNode(newVfModuleNode, 'orchestration-status')
227                         if (orchestrationStatusNode == null) {
228                                 // Node doesn't exist, this should never happen, right?
229                                 new Node(newVfModuleNode, 'orchestration-status', orchestrationStatus)
230                         } else {
231                                 // Node already exists, just give it a new value
232                                 orchestrationStatusNode.setValue(orchestrationStatus)
233                         }
234                         def VfModule newVfModule = new VfModule(newVfModuleNode, vfModule.isOnlyVfModule())
235                         def payload = utils.nodeToString(newVfModuleNode)
236                         
237                         // Construct endpoint
238                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
239                         def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
240                         
241                         
242                         AaiUtil aaiUriUtil = new AaiUtil(this)
243                         def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
244                         logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
245                         
246                         String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "/vf-modules/vf-module/" + UriUtils.encode(vfModuleId, "UTF-8")
247
248                         String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
249
250                         try {
251                                 RESTConfig config = new RESTConfig(endPoint);
252                                 def responseData = ''
253                                 def aaiRequestId = UUID.randomUUID().toString()
254                                 RESTClient client = new RESTClient(config).
255                                         addHeader('X-TransactionId', aaiRequestId).
256                                         addHeader('X-FromAppId', 'MSO').
257                                         addHeader('Content-Type', 'application/xml').
258                                         addHeader('Accept','application/xml');
259                                 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
260                                         client.addAuthorizationHeader(basicAuthCred)
261                                 }
262                                 logDebug('sending PUT to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
263                                 APIResponse response = client.httpPut(payload)
264
265                                 responseData = response.getResponseBodyAsString()
266                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
267                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
268                                 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
269                                 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
270                                 
271                                 // Set the output for this flow.  The updated VfModule is an output, the generic VNF name, and for
272                                 // backward compatibilty, the heat-stack-id is an output
273                                 execution.setVariable('PUAAIVfMod_outVfModule', newVfModule)
274                                 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
275                                 logDebug('Output PUAAIVfMod_vnfName set to ' + vnfName, isDebugLogEnabled)
276                                 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
277                                 execution.setVariable('WorkflowResponse', newVfModule)
278                                 logDebug('Output PUAAIVfMod_outVfModule set for VF Module Id \'' + newVfModule.getElementText('vf-module-id') + '\'', isDebugLogEnabled)
279                                 def heatStackId = newVfModule.getElementText('heat-stack-id')
280                                 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
281                                 logDebug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'', isDebugLogEnabled)
282                         } catch (Exception ex) {
283                                 ex.printStackTrace()
284                                 logDebug('Exception occurred while executing AAI PUT:' + ex.getMessage(), isDebugLogEnabled)
285                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
286                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PUT Failed:' + ex.getMessage())
287                         }
288                         logDebug('Exited ' + method, isDebugLogEnabled)
289                 } catch (BpmnError e) {
290                         throw e;
291                 } catch (Exception e) {
292                         logError('Caught exception in ' + method, e)
293                         createWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
294                 }                               
295         }
296                 
297         /**
298          * Generates a WorkflowException if the AAI query returns a response code other than 200.
299          * 
300          * @param execution The flow's execution instance.
301          */
302         public void handleVnfNotFound(Execution execution) {
303                 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
304                         'execution=' + execution.getId() +
305                         ')'
306                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
307                 logDebug('Entered ' + method, isDebugLogEnabled)
308
309                 logError('Error occurred attempting to query AAI, Response Code ' +
310                         execution.getVariable('PUAAIVfMod_getVnfResponseCode') + ', Error Response ' +
311                         execution.getVariable('PUAAIVfMod_getVnfResponse'))
312                 String processKey = getProcessKey(execution);
313                 WorkflowException exception = new WorkflowException(processKey, 5000,
314                         execution.getVariable('PUAAIVfMod_getVnfResponse'))
315                 execution.setVariable('WorkflowException', exception)
316                 
317                 logDebug('Exited ' + method, isDebugLogEnabled)
318         }
319         
320         /**
321          * Generates a WorkflowException if the VF Module does not pass validation.
322          * 
323          * @param execution The flow's execution instance.
324          */
325         public void handleVfModuleValidationError(Execution execution) {
326                 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
327                         'execution=' + execution.getId() +
328                         ')'
329                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
330                 logDebug('Entered ' + method, isDebugLogEnabled)
331                                 
332                 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
333                 logError(errorMsg)
334                 String processKey = getProcessKey(execution);
335                 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
336                 execution.setVariable('WorkflowException', exception)
337
338                 logDebug('Exited ' + method, isDebugLogEnabled)
339         }
340         
341         /**
342          * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
343          * 
344          * @param execution The flow's execution instance.
345          */
346         public void handleUpdateVfModuleFailure(Execution execution) {
347                 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
348                         'execution=' + execution.getId() +
349                         ')'
350                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
351                 logDebug('Entered ' + method, isDebugLogEnabled)
352
353                 logError('Error occurred attempting to update VF Module in AAI, Response Code ' +
354                         execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode') + ', Error Response ' +
355                         execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
356                 String processKey = getProcessKey(execution);
357                 WorkflowException exception = new WorkflowException(processKey, 5000,
358                         execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
359                 execution.setVariable('WorkflowException', exception)
360                 
361                 logDebug('Exited ' + method, isDebugLogEnabled)
362         }
363 }