2 * ============LICENSE_START=======================================================
\r
4 * ================================================================================
\r
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * ================================================================================
\r
7 * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * you may not use this file except in compliance with the License.
\r
9 * You may obtain a copy of the License at
\r
11 * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * Unless required by applicable law or agreed to in writing, software
\r
14 * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * See the License for the specific language governing permissions and
\r
17 * limitations under the License.
\r
18 * ============LICENSE_END=========================================================
\r
21 package org.openecomp.mso.bpmn.common.scripts
\r
23 import org.camunda.bpm.engine.delegate.BpmnError
\r
24 import org.camunda.bpm.engine.runtime.Execution
\r
25 import org.openecomp.mso.bpmn.core.WorkflowException
\r
26 import org.openecomp.mso.rest.APIResponse
\r
27 import org.openecomp.mso.rest.RESTClient
\r
28 import org.openecomp.mso.rest.RESTConfig
\r
29 import org.springframework.web.util.UriUtils
\r
31 public class PrepareUpdateAAIVfModule extends VfModuleBase {
\r
33 ExceptionUtil exceptionUtil = new ExceptionUtil()
\r
34 private MsoUtils utils = new MsoUtils()
\r
36 * Initialize the flow's variables.
\r
38 * @param execution The flow's execution instance.
\r
40 public void initProcessVariables(Execution execution) {
\r
41 execution.setVariable('prefix', 'PUAAIVfMod_')
\r
42 execution.setVariable('PUAAIVfMod_vnfId', null)
\r
43 execution.setVariable('PUAAIVfMod_vfModuleId', null)
\r
44 execution.setVariable('PUAAIVfMod_vnfName', null)
\r
45 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
\r
46 execution.setVariable('PUAAIVfMod_vfModule', null)
\r
47 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
48 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
\r
49 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
\r
50 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
\r
51 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
\r
52 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
\r
53 execution.setVariable('PUAAIVfMod_outVfModule', null)
\r
57 * Check for missing elements in the received request.
\r
59 * @param execution The flow's execution instance.
\r
61 public void preProcessRequest(Execution execution) {
\r
62 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
63 'execution=' + execution.getId() +
\r
65 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
66 logDebug('Entered ' + method, isDebugLogEnabled)
\r
69 def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
\r
70 logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
\r
71 utils.logAudit("PrepareUpdateAAIVfModule Request : " + xml)
\r
73 initProcessVariables(execution)
\r
75 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
\r
76 execution.setVariable('PUAAIVfMod_vnfId', vnfId)
\r
78 def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
\r
79 execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
\r
81 def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
\r
82 execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
\r
84 logDebug('Exited ' + method, isDebugLogEnabled)
\r
85 } catch (BpmnError e) {
\r
87 } catch (Exception e) {
\r
88 logError('Caught exception in ' + method, e)
\r
89 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
\r
94 * Using the received vnfId, query AAI to get the corresponding Generic VNF.
\r
95 * A 200 response is expected with the Generic VNF in the response body.
\r
97 * @param execution The flow's execution instance.
\r
99 public void getGenericVnf(Execution execution) {
\r
100 def method = getClass().getSimpleName() + '.getGenericVnf(' +
\r
101 'execution=' + execution.getId() +
\r
103 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
104 logDebug('Entered ' + method, isDebugLogEnabled)
\r
107 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
109 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
110 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
111 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
113 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "?depth=1"
\r
115 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
\r
116 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
\r
118 RESTConfig config = new RESTConfig(endPoint);
\r
119 def responseData = ''
\r
120 String aaiRequestId = utils.getRequestID()
\r
121 RESTClient client = new RESTClient(config).
\r
122 addHeader('X-TransactionId', aaiRequestId).
\r
123 addHeader('X-FromAppId', 'MSO').
\r
124 addHeader('Content-Type', 'application/xml').
\r
125 addHeader('Accept','application/xml');
\r
126 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
\r
127 client.addAuthorizationHeader(basicAuthCred)
\r
129 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
\r
130 APIResponse response = client.httpGet()
\r
131 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpGet to AAI")
\r
133 responseData = response.getResponseBodyAsString()
\r
134 execution.setVariable('PUAAIVfMod_getVnfResponseCode', response.getStatusCode())
\r
135 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
\r
137 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
\r
138 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
\r
140 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
141 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
142 } catch (Exception ex) {
\r
143 ex.printStackTrace()
\r
144 logDebug('Exception occurred while executing AAI GET:' + ex.getMessage(), isDebugLogEnabled)
\r
145 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
\r
146 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
\r
148 logDebug('Exited ' + method, isDebugLogEnabled)
\r
149 } catch (BpmnError e) {
\r
151 } catch (Exception e) {
\r
152 logError('Caught exception in ' + method, e)
\r
153 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
\r
158 * Validate the VF Module. That is, confirm that a VF Module with the input VF Module ID
\r
159 * exists in the retrieved Generic VNF. Then, check to make sure that if that VF Module
\r
160 * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
\r
161 * attempting to delete it.
\r
163 * @param execution The flow's execution instance.
\r
165 public void validateVfModule(Execution execution) {
\r
166 def method = getClass().getSimpleName() + '.validateVfModule(' +
\r
167 'execution=' + execution.getId() +
\r
169 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
170 logDebug('Entered ' + method, isDebugLogEnabled)
\r
173 def genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
\r
174 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
175 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
\r
176 def vnfName = getNodeTextForce(genericVnf, 'vnf-name')
\r
177 execution.setVariable('PUAAIVfMod_vnfName', vnfName)
\r
178 def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
\r
179 if (vfModule == null) {
\r
180 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
\r
181 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
\r
182 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
184 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
\r
185 if (isDebugLogEnabled) {
\r
186 logDebug('VF Module \'' + vfModuleId + '\': isBaseVfModule=' + vfModule.isBaseVfModule() +
\r
187 ', isOnlyVfModule=' + vfModule.isOnlyVfModule() + ', new orchestration-status=' + orchestrationStatus,
\r
190 if (vfModule.isBaseVfModule() && !vfModule.isOnlyVfModule() && orchestrationStatus.equals('pending-delete')) {
\r
191 def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
\r
192 '\' 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 + '\''
\r
193 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
\r
194 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
196 execution.setVariable('PUAAIVfMod_vfModule', vfModule)
\r
197 execution.setVariable('PUAAIVfMod_vfModuleOK', true)
\r
201 logDebug('Exited ' + method, isDebugLogEnabled)
\r
202 } catch (BpmnError e) {
\r
204 } catch (Exception e) {
\r
205 logError('Caught exception in ' + method, e)
\r
206 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
\r
211 * Construct and send a PATCH request to AAI to update the VF Module.
\r
213 * @param execution The flow's execution instance.
\r
215 public void updateVfModule(Execution execution) {
\r
216 def method = getClass().getSimpleName() + '.updateVfModule(' +
\r
217 'execution=' + execution.getId() +
\r
219 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
220 logDebug('Entered ' + method, isDebugLogEnabled)
\r
223 // Construct payload
\r
224 def VfModule vfModule = (VfModule) execution.getVariable('PUAAIVfMod_vfModule')
\r
225 def Node newVfModuleNode = vfModule.getNode().clone()
\r
226 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
\r
227 def Node orchestrationStatusNode = utils.getChildNode(newVfModuleNode, 'orchestration-status')
\r
228 if (orchestrationStatusNode == null) {
\r
229 // Node doesn't exist, this should never happen, right?
\r
230 new Node(newVfModuleNode, 'orchestration-status', orchestrationStatus)
\r
232 // Node already exists, just give it a new value
\r
233 orchestrationStatusNode.setValue(orchestrationStatus)
\r
235 def VfModule newVfModule = new VfModule(newVfModuleNode, vfModule.isOnlyVfModule())
\r
236 //def payload = utils.nodeToString(newVfModuleNode)
\r
238 // Construct endpoint
\r
239 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
240 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
\r
243 "vf-module-id": "${vfModuleId}",
\r
244 "orchestration-status": "${orchestrationStatus}"
\r
247 utils.logAudit("VfModule payload : " + payload)
\r
249 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
250 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
251 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
253 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "/vf-modules/vf-module/" + UriUtils.encode(vfModuleId, "UTF-8")
\r
254 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
\r
255 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
\r
257 RESTConfig config = new RESTConfig(endPoint);
\r
258 def responseData = ''
\r
259 def aaiRequestId = utils.getRequestID()
\r
260 RESTClient client = new RESTClient(config).
\r
261 addHeader('X-TransactionId', aaiRequestId).
\r
262 addHeader('X-FromAppId', 'MSO').
\r
263 addHeader('Content-Type', 'application/merge-patch+json').
\r
264 addHeader('Accept','application/json');
\r
265 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
\r
266 client.addAuthorizationHeader(basicAuthCred)
\r
268 logDebug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
\r
269 APIResponse response = client.httpPatch(payload)
\r
270 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
\r
271 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
\r
273 responseData = response.getResponseBodyAsString()
\r
274 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
\r
275 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
\r
276 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
277 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
278 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
\r
279 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
\r
281 // Set the output for this flow. The updated VfModule is an output, the generic VNF name, and for
\r
282 // backward compatibilty, the heat-stack-id is an output
\r
283 execution.setVariable('PUAAIVfMod_outVfModule', newVfModule)
\r
284 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
\r
285 logDebug('Output PUAAIVfMod_vnfName set to ' + vnfName, isDebugLogEnabled)
\r
286 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
\r
287 execution.setVariable('WorkflowResponse', newVfModule)
\r
288 logDebug('Output PUAAIVfMod_outVfModule set for VF Module Id \'' + newVfModule.getElementText('vf-module-id') + '\'', isDebugLogEnabled)
\r
289 def heatStackId = newVfModule.getElementText('heat-stack-id')
\r
290 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
\r
291 logDebug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'', isDebugLogEnabled)
\r
292 } catch (Exception ex) {
\r
293 ex.printStackTrace()
\r
294 logDebug('Exception occurred while executing AAI PUT:' + ex.getMessage(), isDebugLogEnabled)
\r
295 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
\r
296 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PATCH Failed:' + ex.getMessage())
\r
298 logDebug('Exited ' + method, isDebugLogEnabled)
\r
299 } catch (BpmnError e) {
\r
301 } catch (Exception e) {
\r
302 logError('Caught exception in ' + method, e)
\r
303 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
\r
308 * Generates a WorkflowException if the AAI query returns a response code other than 200.
\r
310 * @param execution The flow's execution instance.
\r
312 public void handleVnfNotFound(Execution execution) {
\r
313 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
\r
314 'execution=' + execution.getId() +
\r
316 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
317 logDebug('Entered ' + method, isDebugLogEnabled)
\r
319 logError('Error occurred attempting to query AAI, Response Code ' +
\r
320 execution.getVariable('PUAAIVfMod_getVnfResponseCode') + ', Error Response ' +
\r
321 execution.getVariable('PUAAIVfMod_getVnfResponse'))
\r
322 String processKey = getProcessKey(execution);
\r
323 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
324 execution.getVariable('PUAAIVfMod_getVnfResponse'))
\r
325 execution.setVariable('WorkflowException', exception)
\r
327 logDebug('Exited ' + method, isDebugLogEnabled)
\r
331 * Generates a WorkflowException if the VF Module does not pass validation.
\r
333 * @param execution The flow's execution instance.
\r
335 public void handleVfModuleValidationError(Execution execution) {
\r
336 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
\r
337 'execution=' + execution.getId() +
\r
339 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
340 logDebug('Entered ' + method, isDebugLogEnabled)
\r
342 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
\r
344 utils.logAudit("PrepareUpdateAAIVfModule: Error Message : " + errorMsg)
\r
346 String processKey = getProcessKey(execution);
\r
347 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
\r
348 execution.setVariable('WorkflowException', exception)
\r
350 logDebug('Exited ' + method, isDebugLogEnabled)
\r
354 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
\r
356 * @param execution The flow's execution instance.
\r
358 public void handleUpdateVfModuleFailure(Execution execution) {
\r
359 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
\r
360 'execution=' + execution.getId() +
\r
362 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
363 logDebug('Entered ' + method, isDebugLogEnabled)
\r
365 logError('Error occurred attempting to update VF Module in AAI, Response Code ' +
\r
366 execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode') + ', Error Response ' +
\r
367 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
\r
368 String processKey = getProcessKey(execution);
\r
369 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
370 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
\r
371 execution.setVariable('WorkflowException', exception)
\r
373 logDebug('Exited ' + method, isDebugLogEnabled)
\r