3e7c4f2d49fb27c734edd7c70ac66dc72d5f5594
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / UpdateAAIGenericVnf.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.common.scripts
22
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.delegate.DelegateExecution
25 import org.onap.so.bpmn.core.WorkflowException
26 import org.onap.so.bpmn.core.UrnPropertiesReader
27 import org.onap.so.client.aai.AAIObjectType
28 import org.onap.so.client.aai.entities.uri.AAIResourceUri
29 import org.onap.so.client.aai.entities.uri.AAIUriFactory
30 import org.onap.so.client.graphinventory.entities.uri.Depth
31 import org.onap.so.rest.APIResponse
32 import org.springframework.web.util.UriUtils
33 import org.onap.so.logger.MessageEnum
34 import org.onap.so.logger.MsoLogger
35
36
37
38
39 public class UpdateAAIGenericVnf extends AbstractServiceTaskProcessor {
40         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, UpdateAAIGenericVnf.class);
41
42
43         private XmlParser xmlParser = new XmlParser()
44         ExceptionUtil exceptionUtil = new ExceptionUtil()
45
46         /**
47          * Initialize the flow's variables.
48          *
49          * @param execution The flow's execution instance.
50          */
51         public void initProcessVariables(DelegateExecution execution) {
52                 execution.setVariable('prefix', 'UAAIGenVnf_')
53                 execution.setVariable('UAAIGenVnf_vnfId', null)
54                 execution.setVariable('UAAIGenVnf_personaModelId', null)
55                 execution.setVariable('UAAIGenVnf_personaModelVersion', null)
56                 execution.setVariable("UAAIGenVnf_ipv4OamAddress", null)
57                 execution.setVariable('UAAIGenVnf_managementV6Address', null)
58                 execution.setVariable('UAAIGenVnf_orchestrationStatus', null)
59                 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode' ,null)
60                 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', '')
61                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', null)
62                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', '')
63         }
64
65         /**
66          * Check for missing elements in the received request.
67          *
68          * @param execution The flow's execution instance.
69          */
70         public void preProcessRequest(DelegateExecution execution) {
71                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
72                         'execution=' + execution.getId() +
73                         ')'
74                 msoLogger.trace('Entered ' + method)
75
76                 try {
77                         def xml = execution.getVariable('UpdateAAIGenericVnfRequest')
78                         msoLogger.debug('Received request xml:\n' + xml)
79                         msoLogger.debug("UpdateAAIGenericVnf Request XML: " + xml)
80                         initProcessVariables(execution)
81
82                         def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
83                         execution.setVariable('UAAIGenVnf_vnfId', vnfId)
84
85                         def personaModelId = getNodeTextForce(xml,'persona-model-id')
86                         if (personaModelId != null && !personaModelId.isEmpty()) {
87                                 execution.setVariable('UAAIGenVnf_personaModelId', personaModelId)
88                         }
89
90                         def personaModelVersion = getNodeTextForce(xml,'persona-model-version')
91                         if (personaModelVersion != null && !personaModelVersion.isEmpty()) {
92                                 execution.setVariable('UAAIGenVnf_personaModelVersion', personaModelVersion)
93                         }
94
95                         def ipv4OamAddress = getNodeTextForce(xml, 'ipv4-oam-address')
96                         if (ipv4OamAddress != null && !ipv4OamAddress.isEmpty()) {
97                                 execution.setVariable('UAAIGenVnf_ipv4OamAddress', ipv4OamAddress)
98                         }
99
100                         def managementV6Address = getNodeTextForce(xml, 'management-v6-address')
101                         if (managementV6Address != null && !managementV6Address.isEmpty()) {
102                                 execution.setVariable('UAAIGenVnf_managementV6Address', managementV6Address)
103                         }
104                         
105                         def orchestrationStatus = getNodeTextForce(xml, 'orchestration-status')
106                         if (orchestrationStatus != null && !orchestrationStatus.isEmpty()) {
107                                 execution.setVariable('UAAIGenVnf_orchestrationStatus', orchestrationStatus)
108                         }
109
110                         msoLogger.trace('Exited ' + method)
111                 } catch (BpmnError e) {
112                         throw e;
113                 } catch (Exception e) {
114                         msoLogger.error(e);
115                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
116                 }
117         }
118
119         /**
120          * Using the received vnfId, query AAI to get the corresponding Generic VNF.
121          * A 200 response is expected with the VF Module in the response body.
122          *
123          * @param execution The flow's execution instance.
124          */
125         public void getGenericVnf(DelegateExecution execution) {
126                 def method = getClass().getSimpleName() + '.getGenericVnf(' +
127                         'execution=' + execution.getId() +
128                         ')'
129                 msoLogger.trace('Entered ' + method)
130
131                 try {
132                         def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
133
134                         // Construct endpoint
135                         AaiUtil aaiUriUtil = new AaiUtil(this)
136                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
137                         uri.depth(Depth.ONE)
138                         String endPoint = aaiUriUtil.createAaiUri(uri)
139                         
140                         try {
141                                 msoLogger.debug('sending GET to AAI endpoint \'' + endPoint + '\'')
142                                 msoLogger.debug("Sending GET to AAI endpoint: " + endPoint)
143
144                                 APIResponse response = aaiUriUtil.executeAAIGetCall(execution, endPoint)
145                                 def responseData = response.getResponseBodyAsString()
146                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', response.getStatusCode())
147                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', responseData)
148                                 msoLogger.debug("UpdateAAIGenericVnf Response data: " + responseData)
149                                 msoLogger.debug('Response code:' + response.getStatusCode())
150                                 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
151                         } catch (Exception ex) {
152                                 msoLogger.error(e);
153                                 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
154                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', 500)
155                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', 'AAI GET Failed:' + ex.getMessage())
156                         }
157                         msoLogger.trace('Exited ' + method)
158                 } catch (BpmnError e) {
159                         throw e;
160                 } catch (Exception e) {
161                         msoLogger.error(e);
162                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
163                 }
164         }
165
166         /**
167          * Construct and send a PUT request to AAI to update the Generic VNF.
168          *
169          * @param execution The flow's execution instance.
170          */
171         public void updateGenericVnf(DelegateExecution execution) {
172                 def method = getClass().getSimpleName() + '.updateGenericVnf(' +
173                         'execution=' + execution.getId() +
174                         ')'
175                 msoLogger.trace('Entered ' + method)
176
177                 try {
178                         def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
179                         def genericVnf = execution.getVariable('UAAIGenVnf_getGenericVnfResponse')
180                         def origRequest = execution.getVariable('UpdateAAIGenericVnfRequest')
181
182                         msoLogger.debug("UpdateGenericVnf Request: " + origRequest)
183                         // Confirm resource-version is in retrieved Generic VNF
184                         def Node genericVnfNode = xmlParser.parseText(genericVnf)
185                         if (utils.getChildNode(genericVnfNode, 'resource-version') == null) {
186                                 def msg = 'Can\'t update Generic VNF ' + vnfId + ' since \'resource-version\' is missing'
187                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
188                                 throw new Exception(msg)
189                         }
190
191                         // Handle persona-model-id/persona-model-version
192
193                         def String newPersonaModelId = execution.getVariable('UAAIGenVnf_personaModelId')
194                         def String newPersonaModelVersion = execution.getVariable('UAAIGenVnf_personaModelVersion')
195                         def String personaModelVersionEntry = ""
196                         if (newPersonaModelId != null || newPersonaModelVersion != null) {
197
198                                 // Confirm "new" persona-model-id is same as "current" persona-model-id
199                                 def Node currPersonaModelIdNode = utils.getChildNode(genericVnfNode, 'model-invariant-id')
200                                 if (currPersonaModelIdNode == null) {
201                                         // check the old attribute name
202                                         currPersonaModelIdNode = utils.getChildNode(genericVnfNode, 'persona-model-id')
203                                 }
204                                 def String currPersonaModelId = ''
205                                 if (currPersonaModelIdNode != null) {
206                                         currPersonaModelId = currPersonaModelIdNode.text()
207                                 }
208                                 if (!newPersonaModelId.equals(currPersonaModelId)) {
209                                         def msg = 'Can\'t update Generic VNF ' + vnfId + ' since there is \'persona-model-id\' mismatch between the current and new values'
210                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
211                                         throw new Exception(msg)
212                                 }
213
214                                 // Construct payload
215                                 personaModelVersionEntry = updateGenericVnfNode(origRequest, genericVnfNode, 'model-version-id')
216                         }
217
218                         // Handle ipv4-oam-address
219                         def String ipv4OamAddress = execution.getVariable('UAAIGenVnf_ipv4OamAddress')
220                         def String ipv4OamAddressEntry = ""
221                         if (ipv4OamAddress != null) {
222                                 // Construct payload
223                                 ipv4OamAddressEntry = updateGenericVnfNode(origRequest, genericVnfNode, 'ipv4-oam-address')
224                         }
225
226                         // Handle management-v6-address
227                         def String managementV6Address = execution.getVariable('UAAIGenVnf_managementV6Address')
228                         def String managementV6AddressEntry = ""
229                         if (managementV6Address != null) {
230                                 // Construct payload
231                                 managementV6AddressEntry = updateGenericVnfNode(origRequest, genericVnfNode, 'management-v6-address')
232                         }
233                         
234                         // Handle orchestration-status
235                         def String orchestrationStatus = execution.getVariable('UAAIGenVnf_orchestrationStatus')
236                         def String orchestrationStatusEntry = ""
237                         if (orchestrationStatus != null) {
238                                 // Construct payload
239                                 orchestrationStatusEntry = updateGenericVnfNode(origRequest, genericVnfNode, 'orchestration-status')
240                         }
241
242                         def payload = """
243                                         {       ${personaModelVersionEntry}
244                                                 ${ipv4OamAddressEntry}
245                                                 ${managementV6AddressEntry}
246                                                 ${orchestrationStatusEntry}
247                                                 "vnf-id": "${vnfId}"                                    
248                                         }
249                         """
250
251                         // Construct endpoint
252                         AaiUtil aaiUriUtil = new AaiUtil(this)
253                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
254                         String endPoint = aaiUriUtil.createAaiUri(uri)
255
256                         try {
257                                 msoLogger.debug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload)
258                                 msoLogger.debug("Sending PATCH to AAI endpoint: " + endPoint)
259
260                                 APIResponse response = aaiUriUtil.executeAAIPatchCall(execution, endPoint, payload)
261                                 def responseData = response.getResponseBodyAsString()
262                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', response.getStatusCode())
263                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', responseData)
264                                 msoLogger.debug("UpdateAAIGenericVnf Response Data: " + responseData)
265                                 msoLogger.debug('Response code:' + response.getStatusCode())
266                                 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
267                         } catch (Exception ex) {
268                                 ex.printStackTrace()
269                                 msoLogger.debug('Exception occurred while executing AAI PATCH:' + ex.getMessage())
270                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', 500)
271                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', 'AAI PATCH Failed:' + ex.getMessage())
272                         }
273                         msoLogger.trace('Exited ' + method)
274                 } catch (BpmnError e) {
275                         throw e;
276                 } catch (Exception e) {
277                         msoLogger.error(e);
278                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateGenericVnf(): ' + e.getMessage())
279                 }
280         }
281
282         /**
283          * Sets up json attributes for PATCH request for Update
284          * 
285          * @param origRequest Incoming update request with Generic VNF element(s) to be updated.
286          * @param genericVnf Current Generic VNF retrieved from AAI.
287          * @param element Name of element to be inserted.
288          */
289         public String updateGenericVnfNode(String origRequest, Node genericVnfNode, String elementName) {
290
291                 if (!utils.nodeExists(origRequest, elementName)) {
292                         return ""
293                 }
294                 def elementValue = utils.getNodeText(origRequest, elementName)
295
296                 if (elementValue.equals('DELETE')) {
297                         // Set the element being deleted to null
298                         return """"${elementName}": null,"""
299                 }
300                 else {
301                         return """"${elementName}": "${elementValue}","""               
302                 }
303                 
304         }
305
306         /**
307          * Generates a WorkflowException if the AAI query returns a response code other than 200.
308          *
309          * @param execution The flow's execution instance.
310          */
311         public void handleAAIQueryFailure(DelegateExecution execution) {
312                 def method = getClass().getSimpleName() + '.handleAAIQueryFailure(' +
313                         'execution=' + execution.getId() +
314                         ')'
315                 msoLogger.trace('Entered ' + method)
316
317                 msoLogger.error( 'Error occurred attempting to query AAI, Response Code ' + execution.getVariable('UAAIGenVnf_getGenericVnfResponseCode'));
318                 String processKey = getProcessKey(execution);
319                 WorkflowException exception = new WorkflowException(processKey, 5000,
320                         execution.getVariable('UAAIGenVnf_getGenericVnfResponse'))
321                 execution.setVariable('WorkflowException', exception)
322
323                 msoLogger.debug("Workflow Exception occurred when handling Quering AAI: " + exception.getErrorMessage())
324                 msoLogger.trace('Exited ' + method)
325         }
326
327         /**
328          * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
329          *
330          * @param execution The flow's execution instance.
331          */
332         public void handleUpdateGenericVnfFailure(DelegateExecution execution) {
333                 def method = getClass().getSimpleName() + '.handleUpdateGenericVnfFailure(' +
334                         'execution=' + execution.getId() +
335                         ')'
336                 msoLogger.trace('Entered ' + method)
337
338                 msoLogger.error('Error occurred attempting to update Generic VNF in AAI, Response Code ' + execution.getVariable('UAAIGenVnf_updateGenericVnfResponseCode'));
339
340                 String processKey = getProcessKey(execution);
341                 WorkflowException exception = new WorkflowException(processKey, 5000,
342                         execution.getVariable('UAAIGenVnf_updateGenericVnfResponse'))
343                 execution.setVariable('WorkflowException', exception)
344
345                 msoLogger.debug("Workflow Exception occurred when Updating GenericVnf: " + exception.getErrorMessage())
346                 msoLogger.trace('Exited ' + method)
347         }
348 }