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