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