ConfirmVolumeGroupNameTest improvements
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / VnfAdapterRestV1.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.core.Response
24 import org.apache.commons.lang3.*
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.onap.so.bpmn.core.UrnPropertiesReader
28 import org.onap.so.client.HttpClient
29 import org.onap.so.logger.MessageEnum
30 import org.onap.so.logger.MsoLogger
31 import org.onap.so.utils.TargetEntity
32 import java.util.UUID
33
34
35
36
37 class VnfAdapterRestV1 extends AbstractServiceTaskProcessor {
38         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, VnfAdapterRestV1.class);
39
40
41         ExceptionUtil exceptionUtil = new ExceptionUtil()
42
43         // VNF Response Processing
44         public void preProcessRequest (DelegateExecution execution) {
45                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
46                         'execution=' + execution.getId() +
47                         ')'
48                 msoLogger.trace('Entered ' + method)
49
50                 def prefix="VNFREST_"
51                 execution.setVariable("prefix", prefix)
52                 setSuccessIndicator(execution, false)
53
54                 try {
55                         String request = validateRequest(execution, "mso-request-id")
56
57                         // Get the request type (the name of the root element) from the request
58
59                         Node root = new XmlParser().parseText(request)
60                         String requestType = root.name()
61                         execution.setVariable(prefix + 'requestType', requestType)
62                         msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'requestType = ' + requestType)
63
64                         msoLogger.debug('VnfAdapterRestV1, request: ' + request)
65                         // Get the messageId from the request
66
67                         String messageId = getChildText(root, 'messageId')
68
69                         if ('rollbackVolumeGroupRequest'.equals(requestType)) {
70                                 messageId = getMessageIdForVolumeGroupRollback(root)
71                         }
72
73                         if (messageId == null || messageId.isEmpty()) {
74                                 String msg = getProcessKey(execution) + ': no messageId in ' + requestType
75                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
76                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
77                         }
78
79                         execution.setVariable('VNFAResponse_CORRELATOR', messageId)
80                         msoLogger.debug(getProcessKey(execution) + ': VNFAResponse_CORRELATOR = ' + messageId)
81
82                         // Get the notificationUrl from the request
83
84                         String notificationUrl = getChildText(root, 'notificationUrl')
85
86                         if (notificationUrl == null || notificationUrl.isEmpty()) {
87                                 String msg = getProcessKey(execution) + ': no notificationUrl in ' + requestType
88                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
89                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
90                         }
91
92                         execution.setVariable(prefix + 'notificationUrl', notificationUrl)
93                         msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'notificationUrl = ' + notificationUrl)
94
95                         // Determine the VnfAdapter endpoint
96
97                         String vnfAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.vnf.rest.endpoint", execution)
98
99                         if (vnfAdapterEndpoint == null || vnfAdapterEndpoint.isEmpty()) {
100                                 String msg = getProcessKey(execution) + ': mso:adapters:vnf:rest:endpoint URN mapping is not defined'
101                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
102                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
103                         }
104
105                         while (vnfAdapterEndpoint.endsWith('/')) {
106                                 vnfAdapterEndpoint = vnfAdapterEndpoint.substring(0, vnfAdapterEndpoint.length()-1)
107                         }
108
109                         String vnfAdapterMethod = null
110                         String vnfAdapterUrl = null
111                         String vnfAdapterRequest = request
112
113                         if ('createVfModuleRequest'.equals(requestType)) {
114                                 String vnfId = getChildText(root, 'vnfId')
115
116                                 if (vnfId == null || vnfId.isEmpty()) {
117                                         String msg = getProcessKey(execution) + ': no vnfId in ' + requestType
118                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
119                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
120                                 }
121
122                                 vnfAdapterMethod = 'POST'
123                                 vnfAdapterUrl = vnfAdapterEndpoint + '/' + URLEncoder.encode(vnfId, 'UTF-8') + '/vf-modules'
124
125                         } else if ('updateVfModuleRequest'.equals(requestType)) {
126                                 String vnfId = getChildText(root, 'vnfId')
127
128                                 if (vnfId == null || vnfId.isEmpty()) {
129                                         String msg = getProcessKey(execution) + ': no vnfId in ' + requestType
130                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
131                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
132                                 }
133
134                                 String vfModuleId = getChildText(root, 'vfModuleId')
135
136                                 if (vfModuleId == null || vfModuleId.isEmpty()) {
137                                         String msg = getProcessKey(execution) + ': no vfModuleId in ' + requestType
138                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
139                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
140                                 }
141
142                                 vnfAdapterMethod = 'PUT'
143                                 vnfAdapterUrl = vnfAdapterEndpoint + '/' + URLEncoder.encode(vnfId, 'UTF-8') +
144                                         '/vf-modules/' + URLEncoder.encode(vfModuleId, 'UTF-8')
145
146                         } else if ('deleteVfModuleRequest'.equals(requestType)) {
147                                 String vnfId = getChildText(root, 'vnfId')
148
149                                 if (vnfId == null || vnfId.isEmpty()) {
150                                         String msg = getProcessKey(execution) + ': no vnfId in ' + requestType
151                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
152                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
153                                 }
154
155                                 String vfModuleId = getChildText(root, 'vfModuleId')
156
157                                 if (vfModuleId == null || vfModuleId.isEmpty()) {
158                                         String msg = getProcessKey(execution) + ': no vfModuleId in ' + requestType
159                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
160                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
161                                 }
162
163                                 vnfAdapterMethod = 'DELETE'
164                                 vnfAdapterUrl = vnfAdapterEndpoint + '/' + URLEncoder.encode(vnfId, 'UTF-8') +
165                                         '/vf-modules/' + URLEncoder.encode(vfModuleId, 'UTF-8')
166
167                         } else if ('rollbackVfModuleRequest'.equals(requestType)) {
168                                 Node vfModuleRollbackNode = getChild(root, 'vfModuleRollback')
169
170                                 if (vfModuleRollbackNode == null) {
171                                         String msg = getProcessKey(execution) + ': no vfModuleRollback in ' + requestType
172                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
173                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
174                                 }
175
176                                 String vnfId = getChildText(vfModuleRollbackNode, 'vnfId')
177
178                                 if (vnfId == null || vnfId.isEmpty()) {
179                                         String msg = getProcessKey(execution) + ': no vnfId in ' + requestType
180                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
181                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
182                                 }
183
184                                 String vfModuleId = getChildText(vfModuleRollbackNode, 'vfModuleId')
185
186                                 if (vfModuleId == null || vfModuleId.isEmpty()) {
187                                         String msg = getProcessKey(execution) + ': no vfModuleId in ' + requestType
188                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
189                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
190                                 }
191
192                                 vnfAdapterMethod = 'DELETE'
193                                 vnfAdapterUrl = vnfAdapterEndpoint + '/' + URLEncoder.encode(vnfId, 'UTF-8') +
194                                         '/vf-modules/' + URLEncoder.encode(vfModuleId, 'UTF-8') + '/rollback'
195
196                         } else if ('createVolumeGroupRequest'.equals(requestType)) {
197                                 vnfAdapterMethod = 'POST'
198                                 if (vnfAdapterEndpoint.endsWith('v1/vnfs')) {
199                                         vnfAdapterEndpoint = vnfAdapterEndpoint.substring(0, (vnfAdapterEndpoint.length()-'/vnfs'.length()))
200                                 }
201                                 vnfAdapterUrl = vnfAdapterEndpoint + '/volume-groups'
202
203                         } else if ('updateVolumeGroupRequest'.equals(requestType)) {
204                                 String volumeGroupId = getChildText(root, 'volumeGroupId')
205
206                                 if (volumeGroupId == null || volumeGroupId.isEmpty()) {
207                                         String msg = getProcessKey(execution) + ': no volumeGroupId in ' + requestType
208                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
209                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
210                                 }
211
212                                 vnfAdapterMethod = 'PUT'
213                                 if (vnfAdapterEndpoint.endsWith('v1/vnfs')) {
214                                         vnfAdapterEndpoint = vnfAdapterEndpoint.substring(0, (vnfAdapterEndpoint.length()-'/vnfs'.length()))
215                                 }
216                                 vnfAdapterUrl = vnfAdapterEndpoint + '/volume-groups/' + URLEncoder.encode(volumeGroupId, 'UTF-8')
217
218                         } else if ('deleteVolumeGroupRequest'.equals(requestType)) {
219                                 String volumeGroupId = getChildText(root, 'volumeGroupId')
220
221                                 if (volumeGroupId == null || volumeGroupId.isEmpty()) {
222                                         String msg = getProcessKey(execution) + ': no volumeGroupId in ' + requestType
223                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
224                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
225                                 }
226
227                                 vnfAdapterMethod = 'DELETE'
228                                 if (vnfAdapterEndpoint.endsWith('v1/vnfs')) {
229                                         vnfAdapterEndpoint = vnfAdapterEndpoint.substring(0, (vnfAdapterEndpoint.length()-'/vnfs'.length()))
230                                 }
231                                 vnfAdapterUrl = vnfAdapterEndpoint + '/volume-groups/' + URLEncoder.encode(volumeGroupId, 'UTF-8')
232
233                         } else if ('rollbackVolumeGroupRequest'.equals(requestType)) {
234                                 String volumeGroupId = getVolumeGroupIdFromRollbackRequest(root)
235
236                                 if (volumeGroupId == null || volumeGroupId.isEmpty()) {
237                                         String msg = getProcessKey(execution) + ': no volumeGroupId in ' + requestType
238                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
239                                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
240                                 }
241
242                                 vnfAdapterMethod = 'DELETE'
243                                 if (vnfAdapterEndpoint.endsWith('v1/vnfs')) {
244                                         vnfAdapterEndpoint = vnfAdapterEndpoint.substring(0, (vnfAdapterEndpoint.length()-'/vnfs'.length()))
245                                 }
246                                 vnfAdapterUrl = vnfAdapterEndpoint + '/volume-groups/' + URLEncoder.encode(volumeGroupId, 'UTF-8')  + '/rollback'
247
248                         } else {
249                                 String msg = getProcessKey(execution) + ': Unsupported request type: ' + requestType
250                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
251                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
252                         }
253
254                         execution.setVariable(prefix + 'vnfAdapterMethod', vnfAdapterMethod)
255                         msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'vnfAdapterMethod = ' + vnfAdapterMethod)
256                         execution.setVariable(prefix + 'vnfAdapterUrl', vnfAdapterUrl)
257                         msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'vnfAdapterUrl = ' + vnfAdapterUrl)
258                         execution.setVariable(prefix + 'vnfAdapterRequest', vnfAdapterRequest)
259                         msoLogger.debug(getProcessKey(execution) + ': ' + prefix + 'vnfAdapterRequest = \n' + vnfAdapterRequest)
260
261                         // Get the Basic Auth credentials for the VnfAdapter
262
263                         String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
264
265                         if (basicAuthValue == null || basicAuthValue.isEmpty()) {
266                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, getProcessKey(execution) + ": mso:adapters:po:auth URN mapping is not defined", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
267                         } else {
268                                 try {
269                                         def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution))
270                                         execution.setVariable(prefix + 'basicAuthHeaderValue', encodedString)
271                                 } catch (IOException ex) {
272                                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, getProcessKey(execution) + ": Unable to encode BasicAuth credentials for VnfAdapter", "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
273                                 }
274                         }
275
276                 } catch (BpmnError e) {
277                         msoLogger.debug(" Rethrowing MSOWorkflowException")
278                         throw e
279                 } catch (Exception e) {
280                         String msg = 'Caught exception in ' + method + ": " + e
281                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
282                         msoLogger.debug(msg)
283                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
284                 }
285         }
286
287         public String getVolumeGroupIdFromRollbackRequest(Node root) {
288                 return root.'volumeGroupRollback'.'volumeGroupId'.text()
289         }
290
291         public String getMessageIdForVolumeGroupRollback(Node root) {
292                 return root.'volumeGroupRollback'.'messageId'.text()
293         }
294
295         /**
296          * This method is used instead of an HTTP Connector task because the
297          * connector does not allow DELETE with a body.
298          */
299         public void sendRequestToVnfAdapter(DelegateExecution execution) {
300                 def method = getClass().getSimpleName() + '.sendRequestToVnfAdapter(' +
301                         'execution=' + execution.getId() +
302                         ')'
303                 msoLogger.trace('Entered ' + method)
304
305                 String prefix = execution.getVariable('prefix')
306
307                 try {
308                         String vnfAdapterMethod = execution.getVariable(prefix + 'vnfAdapterMethod')
309                         String vnfAdapterUrl = execution.getVariable(prefix + 'vnfAdapterUrl')
310                         String vnfAdapterRequest = execution.getVariable(prefix + 'vnfAdapterRequest')
311
312                         URL url = new URL(vnfAdapterUrl);
313
314                         HttpClient httpClient = new HttpClient(url, "application/xml", TargetEntity.VNF_ADAPTER)
315                         httpClient.addAdditionalHeader("Authorization", execution.getVariable(prefix + "basicAuthHeaderValue"))
316                         
317                         httpClient.addAdditionalHeader("X-ONAP-RequestID", execution.getVariable("mso-request-id"))
318                         httpClient.addAdditionalHeader("X-ONAP-InvocationID", UUID.randomUUID().toString())
319                         httpClient.addAdditionalHeader("X-ONAP-PartnerName", "SO-VNFAdapter")
320                         Response response;
321
322                         if ("GET".equals(vnfAdapterMethod)) {
323                                 response = httpClient.get()
324                         } else if ("PUT".equals(vnfAdapterMethod)) {
325                                 response = httpClient.put(vnfAdapterRequest)
326                         } else if ("POST".equals(vnfAdapterMethod)) {
327                                 response = httpClient.post(vnfAdapterRequest)
328                         } else if ("DELETE".equals(vnfAdapterMethod)) {
329                                 response = httpClient.delete(vnfAdapterRequest)
330                         } else {
331                                 String msg = 'Unsupported HTTP method "' + vnfAdapterMethod + '" in ' + method + ": " + e
332                                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
333                                 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
334                         }
335
336                         execution.setVariable(prefix + "vnfAdapterStatusCode", response.getStatus())
337                         if(response.hasEntity()){
338                                 execution.setVariable(prefix + "vnfAdapterResponse", response.readEntity(String.class))
339                         }
340                 } catch (BpmnError e) {
341                         throw e
342                 } catch (Exception e) {
343                         String msg = 'Caught exception in ' + method + ": " + e
344                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "");
345                         exceptionUtil.buildAndThrowWorkflowException(execution, 2000, msg)
346                 }
347         }
348
349         public void processCallback(DelegateExecution execution){
350                 def method = getClass().getSimpleName() + '.processCallback(' +
351                         'execution=' + execution.getId() +
352                         ')'
353                 msoLogger.trace('Entered ' + method)
354
355                 String callback = execution.getVariable('VNFAResponse_MESSAGE')
356
357                 try {
358                         msoLogger.debug(getProcessKey(execution) + ": received callback:\n" + callback)
359
360                         // The XML callback is available to the calling flow in any case,
361                         // even if a WorkflowException is generated.
362                         execution.setVariable(getProcessKey(execution) + 'Response', callback)
363                         // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead.
364                         execution.setVariable("WorkflowResponse", callback)
365
366                         Node root = new XmlParser().parseText(callback)
367                         if (root.name().endsWith('Exception')) {
368                                 vnfAdapterWorkflowException(execution, callback)
369                         }
370                 } catch (Exception e) {
371                         e.printStackTrace()
372                         callback = callback == null || String.valueOf(callback).isEmpty() ? "NONE" : callback
373                         String msg = "Received error from VnfAdapter: " + callback
374                         msoLogger.debug(getProcessKey(execution) + ': ' + msg)
375                         exceptionUtil.buildWorkflowException(execution, 7020, msg)
376                 }
377         }
378
379         /**
380          * Tries to parse the response as XML to extract the information to create
381          * a WorkflowException.  If the response cannot be parsed, a more generic
382          * WorkflowException is created.
383          */
384         public void vnfAdapterWorkflowException(DelegateExecution execution, Object response) {
385                 try {
386                         Node root = new XmlParser().parseText(response)
387                         String category = getChildText(root, "category")
388                         category = category == null || category.isEmpty() ? "" : " category='" + category + "'"
389                         String message = getChildText(root, "message")
390                         message = message == null || message.isEmpty() ? "" : " message='" + message + "'"
391                         String rolledBack = getChildText(root, "rolledBack")
392                         rolledBack = rolledBack == null || rolledBack.isEmpty() ? "" : " rolledBack='" + rolledBack + "'"
393                         exceptionUtil.buildWorkflowException(execution, 7020, "Received " + root.name() +
394                                 " from VnfAdapter:" + category + message + rolledBack);
395                 } catch (Exception e) {
396                         response = response == null || String.valueOf(response).isEmpty() ? "NONE" : response
397                         exceptionUtil.buildWorkflowException(execution, 7020, "Received error from VnfAdapter: " + response)
398                 }
399         }
400
401         /**
402          * Gets the named child of the specified node.
403          * @param node the node
404          * @param name the child name
405          * @return the child node, or null if no such child exists
406          */
407         private Node getChild(Node node, String name) {
408                 for (Node child : node.children()) {
409                         if (child.name() == name) {
410                                 return child
411                         }
412                 }
413                 return null
414         }
415
416         /**
417          * Gets the text of the named child of the specified node.
418          * @param node the node
419          * @param name the child name
420          * @return the child node text, or null if no such child exists
421          */
422         private String getChildText(Node node, String name) {
423                 Node child = getChild(node, name)
424                 return child == null ? null : child.text()
425         }
426 }