2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.mso.bpmn.common.scripts
23 import org.camunda.bpm.engine.delegate.BpmnError
24 import org.camunda.bpm.engine.runtime.Execution
25 import org.openecomp.mso.bpmn.core.WorkflowException
26 import org.openecomp.mso.rest.APIResponse
27 import org.openecomp.mso.rest.RESTClient
28 import org.openecomp.mso.rest.RESTConfig
29 import org.springframework.web.util.UriUtils
31 public class PrepareUpdateAAIVfModule extends VfModuleBase {
34 * Initialize the flow's variables.
36 * @param execution The flow's execution instance.
38 public void initProcessVariables(Execution execution) {
39 execution.setVariable('prefix', 'PUAAIVfMod_')
40 execution.setVariable('PUAAIVfMod_vnfId', null)
41 execution.setVariable('PUAAIVfMod_vfModuleId', null)
42 execution.setVariable('PUAAIVfMod_vnfName', null)
43 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
44 execution.setVariable('PUAAIVfMod_vfModule', null)
45 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
46 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
47 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
48 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
49 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
50 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
51 execution.setVariable('PUAAIVfMod_outVfModule', null)
55 * Check for missing elements in the received request.
57 * @param execution The flow's execution instance.
59 public void preProcessRequest(Execution execution) {
60 def method = getClass().getSimpleName() + '.preProcessRequest(' +
61 'execution=' + execution.getId() +
63 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
64 logDebug('Entered ' + method, isDebugLogEnabled)
67 def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
68 logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
69 utils.logAudit("PrepareUpdateAAIVfModule Request : " + xml)
71 initProcessVariables(execution)
73 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
74 execution.setVariable('PUAAIVfMod_vnfId', vnfId)
76 def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
77 execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
79 def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
80 execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
82 logDebug('Exited ' + method, isDebugLogEnabled)
83 } catch (BpmnError e) {
85 } catch (Exception e) {
86 logError('Caught exception in ' + method, e)
87 createWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
92 * Using the received vnfId, query AAI to get the corresponding Generic VNF.
93 * A 200 response is expected with the Generic VNF in the response body.
95 * @param execution The flow's execution instance.
97 public void getGenericVnf(Execution execution) {
98 def method = getClass().getSimpleName() + '.getGenericVnf(' +
99 'execution=' + execution.getId() +
101 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
102 logDebug('Entered ' + method, isDebugLogEnabled)
105 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
107 AaiUtil aaiUriUtil = new AaiUtil(this)
108 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
109 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
111 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "?depth=1"
113 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
114 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
116 RESTConfig config = new RESTConfig(endPoint);
117 def responseData = ''
118 def aaiRequestId = UUID.randomUUID().toString()
119 RESTClient client = new RESTClient(config).
120 addHeader('X-TransactionId', aaiRequestId).
121 addHeader('X-FromAppId', 'MSO').
122 addHeader('Content-Type', 'application/xml').
123 addHeader('Accept','application/xml');
124 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
125 client.addAuthorizationHeader(basicAuthCred)
127 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
128 APIResponse response = client.httpGet()
129 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpGet to AAI")
131 responseData = response.getResponseBodyAsString()
132 execution.setVariable('PUAAIVfMod_getVnfResponseCode', response.getStatusCode())
133 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
135 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
136 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
138 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
139 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
140 } catch (Exception ex) {
142 logDebug('Exception occurred while executing AAI GET:' + ex.getMessage(), isDebugLogEnabled)
143 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
144 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
146 logDebug('Exited ' + method, isDebugLogEnabled)
147 } catch (BpmnError e) {
149 } catch (Exception e) {
150 logError('Caught exception in ' + method, e)
151 createWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
156 * Validate the VF Module. That is, confirm that a VF Module with the input VF Module ID
157 * exists in the retrieved Generic VNF. Then, check to make sure that if that VF Module
158 * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
159 * attempting to delete it.
161 * @param execution The flow's execution instance.
163 public void validateVfModule(Execution execution) {
164 def method = getClass().getSimpleName() + '.validateVfModule(' +
165 'execution=' + execution.getId() +
167 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
168 logDebug('Entered ' + method, isDebugLogEnabled)
171 def genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
172 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
173 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
174 def vnfName = getNodeTextForce(genericVnf, 'vnf-name')
175 execution.setVariable('PUAAIVfMod_vnfName', vnfName)
176 def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
177 if (vfModule == null) {
178 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
179 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
180 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
182 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
183 if (isDebugLogEnabled) {
184 logDebug('VF Module \'' + vfModuleId + '\': isBaseVfModule=' + vfModule.isBaseVfModule() +
185 ', isOnlyVfModule=' + vfModule.isOnlyVfModule() + ', new orchestration-status=' + orchestrationStatus,
188 if (vfModule.isBaseVfModule() && !vfModule.isOnlyVfModule() && orchestrationStatus.equals('pending-delete')) {
189 def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
190 '\' 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 + '\''
191 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
192 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
194 execution.setVariable('PUAAIVfMod_vfModule', vfModule)
195 execution.setVariable('PUAAIVfMod_vfModuleOK', true)
199 logDebug('Exited ' + method, isDebugLogEnabled)
200 } catch (BpmnError e) {
202 } catch (Exception e) {
203 logError('Caught exception in ' + method, e)
204 createWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
209 * Construct and send a PUT request to AAI to update the VF Module.
211 * @param execution The flow's execution instance.
213 public void updateVfModule(Execution execution) {
214 def method = getClass().getSimpleName() + '.updateVfModule(' +
215 'execution=' + execution.getId() +
217 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
218 logDebug('Entered ' + method, isDebugLogEnabled)
222 def VfModule vfModule = (VfModule) execution.getVariable('PUAAIVfMod_vfModule')
223 def Node newVfModuleNode = vfModule.getNode().clone()
224 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
225 def Node orchestrationStatusNode = utils.getChildNode(newVfModuleNode, 'orchestration-status')
226 if (orchestrationStatusNode == null) {
227 // Node doesn't exist, this should never happen, right?
228 new Node(newVfModuleNode, 'orchestration-status', orchestrationStatus)
230 // Node already exists, just give it a new value
231 orchestrationStatusNode.setValue(orchestrationStatus)
233 def VfModule newVfModule = new VfModule(newVfModuleNode, vfModule.isOnlyVfModule())
234 def payload = utils.nodeToString(newVfModuleNode)
236 utils.logAudit("VfModule payload : " + payload)
238 // Construct endpoint
239 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
240 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
243 AaiUtil aaiUriUtil = new AaiUtil(this)
244 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
245 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
247 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "/vf-modules/vf-module/" + UriUtils.encode(vfModuleId, "UTF-8")
248 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
249 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
251 RESTConfig config = new RESTConfig(endPoint);
252 def responseData = ''
253 def aaiRequestId = UUID.randomUUID().toString()
254 RESTClient client = new RESTClient(config).
255 addHeader('X-TransactionId', aaiRequestId).
256 addHeader('X-FromAppId', 'MSO').
257 addHeader('Content-Type', 'application/xml').
258 addHeader('Accept','application/xml');
259 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
260 client.addAuthorizationHeader(basicAuthCred)
262 logDebug('sending PUT to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
263 APIResponse response = client.httpPut(payload)
264 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpPut to AAI")
266 responseData = response.getResponseBodyAsString()
267 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
268 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
269 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
270 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
271 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
272 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
274 // Set the output for this flow. The updated VfModule is an output, the generic VNF name, and for
275 // backward compatibilty, the heat-stack-id is an output
276 execution.setVariable('PUAAIVfMod_outVfModule', newVfModule)
277 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
278 logDebug('Output PUAAIVfMod_vnfName set to ' + vnfName, isDebugLogEnabled)
279 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
280 execution.setVariable('WorkflowResponse', newVfModule)
281 logDebug('Output PUAAIVfMod_outVfModule set for VF Module Id \'' + newVfModule.getElementText('vf-module-id') + '\'', isDebugLogEnabled)
282 def heatStackId = newVfModule.getElementText('heat-stack-id')
283 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
284 logDebug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'', isDebugLogEnabled)
285 } catch (Exception ex) {
287 logDebug('Exception occurred while executing AAI PUT:' + ex.getMessage(), isDebugLogEnabled)
288 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
289 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PUT Failed:' + ex.getMessage())
291 logDebug('Exited ' + method, isDebugLogEnabled)
292 } catch (BpmnError e) {
294 } catch (Exception e) {
295 logError('Caught exception in ' + method, e)
296 createWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
301 * Generates a WorkflowException if the AAI query returns a response code other than 200.
303 * @param execution The flow's execution instance.
305 public void handleVnfNotFound(Execution execution) {
306 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
307 'execution=' + execution.getId() +
309 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
310 logDebug('Entered ' + method, isDebugLogEnabled)
312 logError('Error occurred attempting to query AAI, Response Code ' +
313 execution.getVariable('PUAAIVfMod_getVnfResponseCode') + ', Error Response ' +
314 execution.getVariable('PUAAIVfMod_getVnfResponse'))
315 String processKey = getProcessKey(execution);
316 WorkflowException exception = new WorkflowException(processKey, 5000,
317 execution.getVariable('PUAAIVfMod_getVnfResponse'))
318 execution.setVariable('WorkflowException', exception)
320 logDebug('Exited ' + method, isDebugLogEnabled)
324 * Generates a WorkflowException if the VF Module does not pass validation.
326 * @param execution The flow's execution instance.
328 public void handleVfModuleValidationError(Execution execution) {
329 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
330 'execution=' + execution.getId() +
332 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
333 logDebug('Entered ' + method, isDebugLogEnabled)
335 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
337 utils.logAudit("PrepareUpdateAAIVfModule: Error Message : " + errorMsg)
339 String processKey = getProcessKey(execution);
340 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
341 execution.setVariable('WorkflowException', exception)
343 logDebug('Exited ' + method, isDebugLogEnabled)
347 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
349 * @param execution The flow's execution instance.
351 public void handleUpdateVfModuleFailure(Execution execution) {
352 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
353 'execution=' + execution.getId() +
355 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
356 logDebug('Entered ' + method, isDebugLogEnabled)
358 logError('Error occurred attempting to update VF Module in AAI, Response Code ' +
359 execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode') + ', Error Response ' +
360 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
361 String processKey = getProcessKey(execution);
362 WorkflowException exception = new WorkflowException(processKey, 5000,
363 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
364 execution.setVariable('WorkflowException', exception)
366 logDebug('Exited ' + method, isDebugLogEnabled)