Dynamic Cloud Owner Support
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / PrepareUpdateAAIVfModule.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.camunda.bpm.model.dmn.instance.OrganizationUnit
26 import org.hibernate.engine.jdbc.Size.LobMultiplier
27 import org.onap.so.bpmn.core.WorkflowException
28 import org.onap.aai.domain.yang.GenericVnf
29 import org.onap.so.bpmn.core.UrnPropertiesReader
30 import org.onap.so.client.aai.AAIObjectType
31 import org.onap.so.client.aai.AAIResourcesClient
32 import org.onap.so.client.aai.entities.AAIResultWrapper
33 import org.onap.so.client.aai.entities.uri.AAIResourceUri
34 import org.onap.so.client.aai.entities.uri.AAIUriFactory
35 import org.onap.so.client.graphinventory.entities.uri.Depth
36 import org.onap.so.rest.APIResponse
37 import org.onap.so.rest.RESTClient
38 import org.onap.so.rest.RESTConfig
39 import org.springframework.web.util.UriUtils
40 import org.onap.so.logger.MessageEnum
41 import org.onap.so.logger.MsoLogger
42
43
44
45 public class PrepareUpdateAAIVfModule extends VfModuleBase {
46         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, PrepareUpdateAAIVfModule.class);
47
48
49         ExceptionUtil exceptionUtil = new ExceptionUtil()
50         private MsoUtils utils = new MsoUtils()
51         /**
52          * Initialize the flow's variables.
53          *
54          * @param execution The flow's execution instance.
55          */
56         public void initProcessVariables(DelegateExecution execution) {
57                 execution.setVariable('prefix', 'PUAAIVfMod_')
58                 execution.setVariable('PUAAIVfMod_vnfId', null)
59                 execution.setVariable('PUAAIVfMod_vfModuleId', null)
60                 execution.setVariable('PUAAIVfMod_vnfName', null)
61                 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
62                 execution.setVariable('PUAAIVfMod_vfModule', null)
63                 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
64                 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
65                 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
66                 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
67                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
68                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
69                 execution.setVariable('PUAAIVfMod_outVfModule', null)
70         }
71
72         /**
73          * Check for missing elements in the received request.
74          *
75          * @param execution The flow's execution instance.
76          */
77         public void preProcessRequest(DelegateExecution execution) {
78                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
79                         'execution=' + execution.getId() +
80                         ')'
81                 msoLogger.trace('Entered ' + method)
82
83                 try {
84                         def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
85                         msoLogger.debug('Received request xml:\n' + xml)
86                         msoLogger.debug("PrepareUpdateAAIVfModule Request  : " + xml)
87
88                         initProcessVariables(execution)
89
90                         def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
91                         execution.setVariable('PUAAIVfMod_vnfId', vnfId)
92
93                         def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
94                         execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
95
96                         def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
97                         execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
98
99                         msoLogger.trace('Exited ' + method)
100                 } catch (BpmnError e) {
101                         throw e;
102                 } catch (Exception e) {
103                         msoLogger.error(e)
104                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
105                 }
106         }
107
108         /**
109          * Using the received vnfId, query AAI to get the corresponding Generic VNF.
110          * A 200 response is expected with the Generic VNF in the response body.
111          *
112          * @param execution The flow's execution instance.
113          */
114         public void getGenericVnf(DelegateExecution execution) {
115                 def method = getClass().getSimpleName() + '.getGenericVnf(' +
116                         'execution=' + execution.getId() +
117                         ')'
118                 msoLogger.trace('Entered ' + method)
119
120                 try {
121                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
122
123
124                         try {
125                                 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
126                                 AAIResourcesClient resourceClient = new AAIResourcesClient()
127                                 AAIResultWrapper wrapper = resourceClient.get(uri.depth(Depth.ONE))
128                                 GenericVnf responseData = wrapper.asBean(GenericVnf.class).get()
129
130                                 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
131
132                         } catch (Exception ex) {
133                                 msoLogger.error(ex);
134                                 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
135                                 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
136                                 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
137                         }
138                         msoLogger.trace('Exited ' + method)
139                 } catch (BpmnError e) {
140                         throw e;
141                 } catch (Exception e) {
142                         msoLogger.error(e)
143                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
144                 }
145         }
146
147         /**
148          * Validate the VF Module.  That is, confirm that a VF Module with the input VF Module ID
149          * exists in the retrieved Generic VNF.  Then, check to make sure that if that VF Module
150          * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
151          * attempting to delete it.
152          *
153          * @param execution The flow's execution instance.
154          */
155         public void validateVfModule(DelegateExecution execution) {
156                 def method = getClass().getSimpleName() + '.validateVfModule(' +
157                         'execution=' + execution.getId() +
158                         ')'
159                 msoLogger.trace('Entered ' + method)
160
161                 try {
162                         GenericVnf genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
163                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
164                         def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
165                         def vnfName = genericVnf.getVnfName()
166                         execution.setVariable('PUAAIVfMod_vnfName', vnfName)
167
168                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId)
169                         AAIResourcesClient resourceClient = new AAIResourcesClient()
170
171
172
173                 //      def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
174                         if (!resourceClient.exists(uri)) {
175                                 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
176                                 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
177                                 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
178                         } else {
179                                 AAIResultWrapper wrapper = resourceClient.get(uri)
180                                 org.onap.aai.domain.yang.VfModule vfModule = wrapper.asBean(org.onap.aai.domain.yang.VfModule.class)
181
182                                 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
183                                 if (vfModule.isBaseVfModule && genericVnf.getVfModules().getVfModule().size() > 1 && vfModule.getOrchestrationStatus().equals('pending-delete')) {
184                                         def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
185                                                 '\' 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 + '\''
186                                         execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
187                                         execution.setVariable('PUAAIVfMod_vfModuleOK', false)
188                                 } else {
189                                         execution.setVariable('PUAAIVfMod_vfModule', vfModule)
190                                         execution.setVariable('PUAAIVfMod_vfModuleOK', true)
191                                 }
192                         }
193
194                         msoLogger.trace('Exited ' + method)
195                 } catch (BpmnError e) {
196                         throw e;
197                 } catch (Exception e) {
198                         msoLogger.error(e)
199                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
200                 }
201         }
202
203         /**
204          * Construct and send a PATCH request to AAI to update the VF Module.
205          *
206          * @param execution The flow's execution instance.
207          */
208         public void updateVfModule(DelegateExecution execution) {
209                 def method = getClass().getSimpleName() + '.updateVfModule(' +
210                         'execution=' + execution.getId() +
211                         ')'
212                 msoLogger.trace('Entered ' + method)
213
214                 try {
215                         // Construct payload
216                         org.onap.aai.domain.yang.VfModule vfModule = execution.getVariable('PUAAIVfMod_vfModule')
217
218                         def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
219
220                         vfModule.setOrchestrationStatus(orchestrationStatus)
221
222                         //def payload = utils.nodeToString(newVfModuleNode)
223
224                         // Construct endpoint
225                         def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
226                         def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
227
228                         def payload = """{
229                                         "vf-module-id": "${vfModuleId}",
230                                         "orchestration-status": "${orchestrationStatus}"
231                                 }"""
232
233                         msoLogger.debug("VfModule payload : " + payload)
234
235                         AaiUtil aaiUtil = new AaiUtil(this)
236                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId)
237                         uri.depth(Depth.ONE)
238                         String endPoint = aaiUtil.createAaiUri(uri)
239
240                         msoLogger.debug("PrepareUpdateAAIVfModule: AAI endPoint  : " + endPoint)
241                         String basicAuthCred = utils.getBasicAuth(UrnPropertiesReader.getVariable("aai.auth", execution),UrnPropertiesReader.getVariable("mso.msoKey", execution))
242                         try {
243                                 RESTConfig config = new RESTConfig(endPoint);
244                                 def responseData = ''
245                 def aaiRequestId = utils.getRequestID()
246                                 RESTClient client = new RESTClient(config).
247                                         addHeader('X-TransactionId', aaiRequestId).
248                                         addHeader('X-FromAppId', 'MSO').
249                                         addHeader('Content-Type', 'application/merge-patch+json').
250                                         addHeader('Accept','application/json');
251                                 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
252                                         client.addAuthorizationHeader(basicAuthCred)
253                                 }
254                                 msoLogger.debug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload)
255                                 APIResponse response = client.httpPatch(payload)
256                                 msoLogger.debug("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
257
258                                 responseData = response.getResponseBodyAsString()
259                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
260                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
261                                 msoLogger.debug('Response code:' + response.getStatusCode())
262                                 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
263                                 msoLogger.debug("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
264                                 msoLogger.debug("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
265
266                                 // Set the output for this flow.  The updated VfModule is an output, the generic VNF name, and for
267                                 // backward compatibilty, the heat-stack-id is an output
268                                 execution.setVariable('PUAAIVfMod_outVfModule', vfModule)
269                                 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
270                                 msoLogger.debug('Output PUAAIVfMod_vnfName set to ' + vnfName)
271                                 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
272                                 execution.setVariable('WorkflowResponse', vfModule)
273
274                                 def heatStackId = vfModule.getHeatStackId()
275                                 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
276                                 msoLogger.debug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'')
277                         } catch (Exception ex) {
278                                 ex.printStackTrace()
279                                 msoLogger.debug('Exception occurred while executing AAI PUT:' + ex.getMessage())
280                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
281                                 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PATCH Failed:' + ex.getMessage())
282                         }
283                         msoLogger.trace('Exited ' + method)
284                 } catch (BpmnError e) {
285                         throw e;
286                 } catch (Exception e) {
287                         msoLogger.error(e)
288                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
289                 }
290         }
291
292         /**
293          * Generates a WorkflowException if the AAI query returns a response code other than 200.
294          *
295          * @param execution The flow's execution instance.
296          */
297         public void handleVnfNotFound(DelegateExecution execution) {
298                 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
299                         'execution=' + execution.getId() +
300                         ')'
301                 msoLogger.trace('Entered ' + method)
302
303                 msoLogger.error('Error occurred attempting to query AAI, Response Code ' + execution.getVariable('PUAAIVfMod_getVnfResponseCode'));
304                 String processKey = getProcessKey(execution);
305                 WorkflowException exception = new WorkflowException(processKey, 5000,
306                         execution.getVariable('PUAAIVfMod_getVnfResponse'))
307                 execution.setVariable('WorkflowException', exception)
308
309                 msoLogger.trace('Exited ' + method)
310         }
311
312         /**
313          * Generates a WorkflowException if the VF Module does not pass validation.
314          *
315          * @param execution The flow's execution instance.
316          */
317         public void handleVfModuleValidationError(DelegateExecution execution) {
318                 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
319                         'execution=' + execution.getId() +
320                         ')'
321                 msoLogger.trace('Entered ' + method)
322
323                 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
324                 msoLogger.error(errorMsg);
325                 msoLogger.debug("PrepareUpdateAAIVfModule: Error Message : " + errorMsg)
326
327                 String processKey = getProcessKey(execution);
328                 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
329                 execution.setVariable('WorkflowException', exception)
330
331                 msoLogger.trace('Exited ' + method)
332         }
333
334         /**
335          * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
336          *
337          * @param execution The flow's execution instance.
338          */
339         public void handleUpdateVfModuleFailure(DelegateExecution execution) {
340                 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
341                         'execution=' + execution.getId() +
342                         ')'
343                 msoLogger.trace('Entered ' + method)
344
345                 msoLogger.error('Error occurred attempting to update VF Module in AAI, Response Code ' + execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode'));
346                 String processKey = getProcessKey(execution);
347                 WorkflowException exception = new WorkflowException(processKey, 5000,
348                         execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
349                 execution.setVariable('WorkflowException', exception)
350
351                 msoLogger.trace('Exited ' + method)
352         }
353 }