AT&T 1712 and 1802 release code
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / openecomp / mso / bpmn / common / scripts / PrepareUpdateAAIVfModule.groovy
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * ONAP - SO\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.delegate.DelegateExecution\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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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(DelegateExecution 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