014dfb40c553b47458e223fc8ac2182296b3b1fe
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / UpdateAAIVfModule.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 javax.ws.rs.NotFoundException
24
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.onap.so.bpmn.core.WorkflowException
28 import org.onap.so.client.aai.AAIObjectType
29 import org.onap.so.client.aai.entities.uri.AAIResourceUri
30 import org.onap.so.client.aai.entities.uri.AAIUriFactory
31 import org.onap.so.logger.MsoLogger
32
33
34 public class UpdateAAIVfModule extends AbstractServiceTaskProcessor {
35         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, UpdateAAIVfModule.class);
36
37
38         private XmlParser xmlParser = new XmlParser()
39         ExceptionUtil exceptionUtil = new ExceptionUtil()
40
41         /**
42          * Initialize the flow's variables.
43          *
44          * @param execution The flow's execution instance.
45          */
46         public void initProcessVariables(DelegateExecution execution) {
47                 execution.setVariable('prefix', 'UAAIVfMod_')
48                 execution.setVariable('UAAIVfMod_vnfId', null)
49                 execution.setVariable('UAAIVfMod_vfModuleId', null)
50                 execution.setVariable('UAAIVfMod_orchestrationStatus', null)
51                 execution.setVariable('UAAIVfMod_heatStackId', null)
52                 execution.setVariable('UAAIVfMod_volumeGroupId', null)
53                 execution.setVariable('UAAIVfMod_getVfModuleResponseCode' ,null)
54                 execution.setVariable('UAAIVfMod_getVfModuleResponse', '')
55                 execution.setVariable('UAAIVfMod_updateVfModuleResponseCode', null)
56                 execution.setVariable('UAAIVfMod_updateVfModuleResponse', '')
57         }
58
59         /**
60          * Check for missing elements in the received request.
61          *
62          * @param execution The flow's execution instance.
63          */
64         public void preProcessRequest(DelegateExecution execution) {
65                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
66                         'execution=' + execution.getId() +
67                         ')'
68                 msoLogger.trace('Entered ' + method)
69
70                 try {
71                         def xml = execution.getVariable('UpdateAAIVfModuleRequest')
72                         msoLogger.debug('Received request xml:\n' + xml)
73                         initProcessVariables(execution)
74
75                         def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
76                         execution.setVariable('UAAIVfMod_vnfId', vnfId)
77
78                         def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
79                         execution.setVariable('UAAIVfMod_vfModuleId', vfModuleId)
80
81                         msoLogger.trace('Exited ' + method)
82                 } catch (BpmnError e) {
83                         throw e;
84                 } catch (Exception e) {
85                         msoLogger.error(e);
86                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
87                 }
88         }
89
90         /**
91          * Using the received vnfId and vfModuleId, query AAI to get the corresponding VF Module.
92          * A 200 response is expected with the VF Module in the response body.
93          *
94          * @param execution The flow's execution instance.
95          */
96         public void getVfModule(DelegateExecution execution) {
97                 def method = getClass().getSimpleName() + '.getVfModule(' +
98                         'execution=' + execution.getId() +
99                         ')'
100                 msoLogger.trace('Entered ' + method)
101
102                 try {
103                         def vnfId = execution.getVariable('UAAIVfMod_vnfId')
104                         def vfModuleId = execution.getVariable('UAAIVfMod_vfModuleId')
105                         try {
106                                 AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
107                                 Optional<org.onap.aai.domain.yang.VfModule> vfModule = getAAIClient().get(org.onap.aai.domain.yang.VfModule.class, resourceUri)
108                                 if (vfModule.isPresent()) {
109                                         execution.setVariable('UAAIVfMod_getVfModuleResponseCode', 200)
110                                         execution.setVariable('UAAIVfMod_getVfModuleResponse', vfModule.get())
111                                 } else {
112                                         execution.setVariable('UAAIVfMod_getVfModuleResponseCode', 404)
113                                         execution.setVariable('UAAIVfMod_getVfModuleResponse', "VF Module not found in AAI")
114                                 }
115                         } catch (Exception ex) {
116                                 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
117                                 execution.setVariable('UAAIVfMod_getVfModuleResponseCode', 500)
118                                 execution.setVariable('UAAIVfMod_getVfModuleResponse', 'AAI GET Failed:' + ex.getMessage())
119                         }
120                 } catch (BpmnError e) {
121                         throw e;
122                 } catch (Exception e) {
123                         msoLogger.error(e);
124                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVfModule(): ' + e.getMessage())
125                 }
126         }
127
128         /**
129          * Construct and send a PATCH request to AAI to update the VF Module.
130          *
131          * @param execution The flow's execution instance.
132          */
133         public void updateVfModule(DelegateExecution execution) {
134                 def method = getClass().getSimpleName() + '.updateVfModule(' +
135                         'execution=' + execution.getId() +
136                         ')'
137                 msoLogger.trace('Entered ' + method)
138
139                 try {
140                         def vnfId = execution.getVariable('UAAIVfMod_vnfId')
141                         def vfModuleId = execution.getVariable('UAAIVfMod_vfModuleId')
142                         org.onap.aai.domain.yang.VfModule vfModule = execution.getVariable('UAAIVfMod_getVfModuleResponse')
143                         def origRequest = execution.getVariable('UpdateAAIVfModuleRequest')
144
145                         msoLogger.debug("UpdateAAIVfModule request: " + origRequest)
146                         // Handle persona-model-id/persona-model-version
147                         def boolean doPersonaModelVersion = true
148                         def String newPersonaModelId = utils.getNodeText(origRequest, 'persona-model-id')
149                         def String newPersonaModelVersion = utils.getNodeText(origRequest, 'persona-model-version')
150                         if ((newPersonaModelId == null) || (newPersonaModelVersion == null)) {
151                                 doPersonaModelVersion = false
152                         } else {
153                                 // Confirm "new" persona-model-id is same as "current" persona-model-id
154                                 def String currPersonaModelId = vfModule.getModelInvariantId()
155                                 if (currPersonaModelId == null) {
156                                         // check the old attribute name
157                                         currPersonaModelId = vfModule.getModelVersionId()
158                                 }
159                                 if (currPersonaModelId == null) {
160                                         currPersonaModelId = ''
161                                 }
162                                 if (!newPersonaModelId.equals(currPersonaModelId)) {
163                                         def msg = 'Can\'t update VF Module ' + vfModuleId + ' since there is \'persona-model-id\' mismatch between the current and new values'
164                                         msoLogger.error(msg)
165                                         throw new Exception(msg)
166                                 }
167                         }
168                         
169                         // Construct payload
170                         String orchestrationStatusEntry = updateVfModuleNode(origRequest , 'orchestration-status')
171                         String heatStackIdEntry = updateVfModuleNode(origRequest,  'heat-stack-id')
172                         String personaModelVersionEntry = ""
173                         if (doPersonaModelVersion) {
174                                 personaModelVersionEntry = updateVfModuleNode(origRequest,  'persona-model-version')
175                         }
176                         String contrailServiceInstanceFqdnEntry = updateVfModuleNode(origRequest,  'contrail-service-instance-fqdn')
177                         def payload = """
178                                         {       ${orchestrationStatusEntry}
179                                                 ${heatStackIdEntry}
180                                                 ${personaModelVersionEntry}
181                                                 ${contrailServiceInstanceFqdnEntry}
182                                                 "vf-module-id": "${vfModuleId}"                                         
183                                         }
184                         """
185
186             try {
187                 AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId)
188                 getAAIClient().update(resourceUri, payload)
189             }catch(NotFoundException ignored){
190                 msoLogger.debug("VF-Module not found!!")
191                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "vf-module " + vfModuleId + " not found for under vnf " + vnfId + " in A&AI!")
192             }
193             catch(Exception ex){
194                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, 'Exception occurred while executing AAI PATCH:' + ex.getMessage())
195             }
196                 } catch (BpmnError e) {
197                         throw e;
198                 } catch (Exception e) {
199                         msoLogger.error(e);
200                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
201                 }
202         }
203
204         /**
205          * Sets up json attributes for PATCH request for Update
206          *
207          * @param origRequest Incoming update request with VF Module elements to be updated.
208          * @param element Name of element to be inserted.
209          */     
210         private String updateVfModuleNode(String origRequest, String elementName) {
211
212                 if (!utils.nodeExists(origRequest, elementName)) {
213                         return "" 
214                 }
215                 def elementValue = utils.getNodeText(origRequest, elementName)
216
217                 if (elementValue.equals('DELETE')) {
218                         // Set the element being deleted to null
219                         return """"${elementName}": null,"""
220                 }
221                 else {
222                         return """"${elementName}": "${elementValue}","""
223                 }               
224         }
225
226         /**
227          * Generates a WorkflowException if the AAI query returns a response code other than 200.
228          *
229          * @param execution The flow's execution instance.
230          */
231         public void handleAAIQueryFailure(DelegateExecution execution) {
232                 def method = getClass().getSimpleName() + '.handleAAIQueryFailure(' +
233                         'execution=' + execution.getId() +
234                         ')'
235                 msoLogger.trace('Entered ' + method)
236
237                 msoLogger.error( 'Error occurred attempting to query AAI, Response Code ' + execution.getVariable('UAAIVfMod_getVfModuleResponseCode'));
238                 String processKey = getProcessKey(execution);
239                 WorkflowException exception = new WorkflowException(processKey, 5000,
240                         execution.getVariable('UAAIVfMod_getVfModuleResponse'))
241                 execution.setVariable('WorkflowException', exception)
242                 msoLogger.debug("UpdateAAIVfModule query failure: " + exception.getErrorMessage())
243                 msoLogger.trace('Exited ' + method)
244         }
245 }