Merge remote-tracking branch 'origin/dublin' into 'origin/master'
[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  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts
24
25 import com.google.common.base.Strings
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.aai.domain.yang.GenericVnf
29 import org.onap.so.bpmn.core.WorkflowException
30 import org.onap.so.client.aai.AAIObjectType
31 import org.onap.so.client.aai.entities.uri.AAIResourceUri
32 import org.onap.so.client.aai.entities.uri.AAIUriFactory
33 import org.onap.so.client.graphinventory.entities.uri.Depth
34 import org.onap.so.logger.ErrorCode
35 import org.onap.so.logger.MessageEnum
36 import org.slf4j.Logger
37 import org.slf4j.LoggerFactory
38
39
40
41
42 public class UpdateAAIGenericVnf extends AbstractServiceTaskProcessor {
43     private static final Logger logger = LoggerFactory.getLogger( UpdateAAIGenericVnf.class);
44
45
46         private XmlParser xmlParser = new XmlParser()
47         ExceptionUtil exceptionUtil = new ExceptionUtil()
48
49         /**
50          * Initialize the flow's variables.
51          *
52          * @param execution The flow's execution instance.
53          */
54         public void initProcessVariables(DelegateExecution execution) {
55                 execution.setVariable('prefix', 'UAAIGenVnf_')
56                 execution.setVariable('UAAIGenVnf_vnfId', null)
57                 execution.setVariable('UAAIGenVnf_personaModelId', null)
58                 execution.setVariable('UAAIGenVnf_personaModelVersion', null)
59                 execution.setVariable("UAAIGenVnf_ipv4OamAddress", null)
60                 execution.setVariable('UAAIGenVnf_managementV6Address', null)
61                 execution.setVariable('UAAIGenVnf_orchestrationStatus', null)
62                 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode' ,null)
63                 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', '')
64                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', null)
65                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', '')
66         }
67
68         /**
69          * Check for missing elements in the received request.
70          *
71          * @param execution The flow's execution instance.
72          */
73         public void preProcessRequest(DelegateExecution execution) {
74                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
75                         'execution=' + execution.getId() +
76                         ')'
77                 logger.trace('Entered ' + method)
78
79                 try {
80                         def xml = execution.getVariable('UpdateAAIGenericVnfRequest')
81                         logger.debug('Received request xml:\n' + xml)
82                         logger.debug("UpdateAAIGenericVnf Request XML: " + xml)
83                         initProcessVariables(execution)
84
85                         def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
86                         execution.setVariable('UAAIGenVnf_vnfId', vnfId)
87
88                         def personaModelId = getNodeTextForce(xml,'persona-model-id')
89                         if (personaModelId != null && !personaModelId.isEmpty()) {
90                                 execution.setVariable('UAAIGenVnf_personaModelId', personaModelId)
91                         }
92
93                         def personaModelVersion = getNodeTextForce(xml,'persona-model-version')
94                         if (personaModelVersion != null && !personaModelVersion.isEmpty()) {
95                                 execution.setVariable('UAAIGenVnf_personaModelVersion', personaModelVersion)
96                         }
97
98                         def ipv4OamAddress = getNodeTextForce(xml, 'ipv4-oam-address')
99                         if (ipv4OamAddress != null && !ipv4OamAddress.isEmpty()) {
100                                 execution.setVariable('UAAIGenVnf_ipv4OamAddress', ipv4OamAddress)
101                         }
102
103                         def managementV6Address = getNodeTextForce(xml, 'management-v6-address')
104                         if (managementV6Address != null && !managementV6Address.isEmpty()) {
105                                 execution.setVariable('UAAIGenVnf_managementV6Address', managementV6Address)
106                         }
107
108                         def orchestrationStatus = getNodeTextForce(xml, 'orchestration-status')
109                         if (orchestrationStatus != null && !orchestrationStatus.isEmpty()) {
110                                 execution.setVariable('UAAIGenVnf_orchestrationStatus', orchestrationStatus)
111                         }
112
113                         logger.trace('Exited ' + method)
114                 } catch (BpmnError e) {
115                         throw e
116                 } catch (Exception e) {
117                         logger.error(e)
118                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
119                 }
120         }
121
122         /**
123          * Using the received vnfId, query AAI to get the corresponding Generic VNF.
124          * A 200 response is expected with the VF Module in the response body.
125          *
126          * @param execution The flow's execution instance.
127          */
128         public void getGenericVnf(DelegateExecution execution) {
129                 def method = getClass().getSimpleName() + '.getGenericVnf(' +
130                         'execution=' + execution.getId() +
131                         ')'
132                 logger.trace('Entered ' + method)
133
134                 try {
135                         def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
136
137                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
138                         uri.depth(Depth.ONE)
139                         try {
140                                 Optional<GenericVnf> genericVnf = getAAIClient().get(GenericVnf.class,uri)
141                                 if(genericVnf.isPresent()){
142                                         execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', 200)
143                                         execution.setVariable('UAAIGenVnf_getGenericVnfResponse', genericVnf.get())
144                                 }else{
145                                         execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', 404)
146                                         execution.setVariable('UAAIGenVnf_getGenericVnfResponse', "Generic VNF not found for VNF ID: "+vnfId)
147                                 }
148                         }catch (Exception ex) {
149                                 logger.error(ex.getMessage())
150                                 logger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
151                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', 500)
152                                 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', 'AAI GET Failed:' + ex.getMessage())
153                         }
154                         logger.trace('Exited ' + method)
155                 } catch (Exception e) {
156                         logger.error(e)
157                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
158                 }
159         }
160
161         /**
162          * Construct and send a PUT request to AAI to update the Generic VNF.
163          *
164          * @param execution The flow's execution instance.
165          */
166         public void updateGenericVnf(DelegateExecution execution) {
167                 def method = getClass().getSimpleName() + '.updateGenericVnf(' +
168                         'execution=' + execution.getId() +
169                         ')'
170                 logger.trace('Entered ' + method)
171
172                 try {
173                         def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
174                         GenericVnf genericVnf = execution.getVariable('UAAIGenVnf_getGenericVnfResponse')
175                         def origRequest = execution.getVariable('UpdateAAIGenericVnfRequest')
176
177                         logger.debug("UpdateGenericVnf Request: " + origRequest)
178                         // Handle persona-model-id/persona-model-version
179
180                         String newPersonaModelId = execution.getVariable('UAAIGenVnf_personaModelId')
181                         String newPersonaModelVersion = execution.getVariable('UAAIGenVnf_personaModelVersion')
182                         String personaModelVersionEntry = null
183                         if (newPersonaModelId != null || newPersonaModelVersion != null) {
184                                 if (newPersonaModelId != genericVnf.getModelInvariantId()) {
185                                         def msg = 'Can\'t update Generic VNF ' + vnfId + ' since there is \'persona-model-id\' mismatch between the current and new values'
186                                         logger.error(Strings.repeat("{} ", 4), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg, "BPMN",
187                                                         ErrorCode.UnknownError.getValue())
188                                         throw new Exception(msg)
189                                 }
190
191                                 // Construct payload
192                                 personaModelVersionEntry = updateGenericVnfNode(origRequest, 'model-version-id')
193                         }
194
195                         // Handle ipv4-oam-address
196                         String ipv4OamAddress = execution.getVariable('UAAIGenVnf_ipv4OamAddress')
197                         String ipv4OamAddressEntry = null
198                         if (ipv4OamAddress != null) {
199                                 // Construct payload
200                                 ipv4OamAddressEntry = updateGenericVnfNode(origRequest, 'ipv4-oam-address')
201                         }
202
203                         // Handle management-v6-address
204                         String managementV6Address = execution.getVariable('UAAIGenVnf_managementV6Address')
205                         String managementV6AddressEntry = null
206                         if (managementV6Address != null) {
207                                 // Construct payload
208                                 managementV6AddressEntry = updateGenericVnfNode(origRequest, 'management-v6-address')
209                         }
210
211                         // Handle orchestration-status
212                         String orchestrationStatus = execution.getVariable('UAAIGenVnf_orchestrationStatus')
213                         String orchestrationStatusEntry = null
214                         if (orchestrationStatus != null) {
215                                 // Construct payload
216                                 orchestrationStatusEntry = updateGenericVnfNode(origRequest, 'orchestration-status')
217                         }
218
219                         org.onap.aai.domain.yang.GenericVnf payload = new org.onap.aai.domain.yang.GenericVnf();
220                         payload.setVnfId(vnfId)
221                         payload.setPersonaModelVersion(personaModelVersionEntry)
222                         payload.setIpv4OamAddress(ipv4OamAddressEntry)
223                         payload.setManagementV6Address(managementV6AddressEntry)
224                         payload.setOrchestrationStatus(orchestrationStatusEntry)
225
226                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
227
228                         try {
229                                 getAAIClient().update(uri,payload)
230                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', 200)
231                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', "Success")
232                         } catch (Exception ex) {
233                                 logger.debug('Exception occurred while executing AAI PATCH: {}', ex.getMessage(), ex)
234                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', 500)
235                                 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', 'AAI PATCH Failed:' + ex.getMessage())
236                         }
237                         logger.trace('Exited ' + method)
238                 } catch (Exception e) {
239                         logger.error(e)
240                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateGenericVnf(): ' + e.getMessage())
241                 }
242         }
243
244         /**
245          * Sets up json attributes for PATCH request for Update
246          *
247          * @param origRequest Incoming update request with Generic VNF element(s) to be updated.
248          * @param genericVnf Current Generic VNF retrieved from AAI.
249          * @param element Name of element to be inserted.
250          */
251         public String updateGenericVnfNode(String origRequest, String elementName) {
252
253                 if (!utils.nodeExists(origRequest, elementName)) {
254                         return null
255                 }
256                 def elementValue = utils.getNodeText(origRequest, elementName)
257
258                 if (elementValue == 'DELETE') {
259                         // Set the element being deleted to empty string
260                         return ""
261                 }
262                 else {
263                         return elementValue
264                 }
265
266         }
267
268         /**
269          * Generates a WorkflowException if the AAI query returns a response code other than 200.
270          *
271          * @param execution The flow's execution instance.
272          */
273         public void handleAAIQueryFailure(DelegateExecution execution) {
274                 def method = getClass().getSimpleName() + '.handleAAIQueryFailure(' +
275                         'execution=' + execution.getId() +
276                         ')'
277                 logger.trace('Entered ' + method)
278
279                 logger.error('Error occurred attempting to query AAI, Response Code ' + execution.getVariable('UAAIGenVnf_getGenericVnfResponseCode'))
280                 String processKey = getProcessKey(execution)
281                 WorkflowException exception = new WorkflowException(processKey, 5000,
282                         execution.getVariable('UAAIGenVnf_getGenericVnfResponse'))
283                 execution.setVariable('WorkflowException', exception)
284
285                 logger.debug("Workflow Exception occurred when handling Quering AAI: " + exception.getErrorMessage())
286                 logger.trace('Exited ' + method)
287         }
288
289         /**
290          * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
291          *
292          * @param execution The flow's execution instance.
293          */
294         public void handleUpdateGenericVnfFailure(DelegateExecution execution) {
295                 def method = getClass().getSimpleName() + '.handleUpdateGenericVnfFailure(' +
296                         'execution=' + execution.getId() +
297                         ')'
298                 logger.trace('Entered ' + method)
299
300                 logger.error('Error occurred attempting to update Generic VNF in AAI, Response Code ' + execution.getVariable('UAAIGenVnf_updateGenericVnfResponseCode'))
301
302                 String processKey = getProcessKey(execution)
303                 WorkflowException exception = new WorkflowException(processKey, 5000,
304                         execution.getVariable('UAAIGenVnf_updateGenericVnfResponse'))
305                 execution.setVariable('WorkflowException', exception)
306
307                 logger.debug("Workflow Exception occurred when Updating GenericVnf: " + exception.getErrorMessage())
308                 logger.trace('Exited ' + method)
309         }
310 }