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