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
35 * Initialize the flow's variables.
\r
37 * @param execution The flow's execution instance.
\r
39 public void initProcessVariables(Execution execution) {
\r
40 execution.setVariable('prefix', 'PUAAIVfMod_')
\r
41 execution.setVariable('PUAAIVfMod_vnfId', null)
\r
42 execution.setVariable('PUAAIVfMod_vfModuleId', null)
\r
43 execution.setVariable('PUAAIVfMod_vnfName', null)
\r
44 execution.setVariable('PUAAIVfMod_orchestrationStatus', null)
\r
45 execution.setVariable('PUAAIVfMod_vfModule', null)
\r
46 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
47 execution.setVariable('PUAAIVfMod_vfModuleValidationError', null)
\r
48 execution.setVariable('PUAAIVfMod_getVnfResponseCode' ,null)
\r
49 execution.setVariable('PUAAIVfMod_getVnfResponse', '')
\r
50 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', null)
\r
51 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', '')
\r
52 execution.setVariable('PUAAIVfMod_outVfModule', null)
\r
56 * Check for missing elements in the received request.
\r
58 * @param execution The flow's execution instance.
\r
60 public void preProcessRequest(Execution execution) {
\r
61 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
62 'execution=' + execution.getId() +
\r
64 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
65 logDebug('Entered ' + method, isDebugLogEnabled)
\r
68 def xml = execution.getVariable('PrepareUpdateAAIVfModuleRequest')
\r
69 logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
\r
70 utils.logAudit("PrepareUpdateAAIVfModule Request : " + xml)
\r
72 initProcessVariables(execution)
\r
74 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
\r
75 execution.setVariable('PUAAIVfMod_vnfId', vnfId)
\r
77 def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
\r
78 execution.setVariable('PUAAIVfMod_vfModuleId', vfModuleId)
\r
80 def orchestrationStatus = getRequiredNodeText(execution, xml,'orchestration-status')
\r
81 execution.setVariable('PUAAIVfMod_orchestrationStatus', orchestrationStatus)
\r
83 logDebug('Exited ' + method, isDebugLogEnabled)
\r
84 } catch (BpmnError e) {
\r
86 } catch (Exception e) {
\r
87 logError('Caught exception in ' + method, e)
\r
88 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
\r
93 * Using the received vnfId, query AAI to get the corresponding Generic VNF.
\r
94 * A 200 response is expected with the Generic VNF in the response body.
\r
96 * @param execution The flow's execution instance.
\r
98 public void getGenericVnf(Execution execution) {
\r
99 def method = getClass().getSimpleName() + '.getGenericVnf(' +
\r
100 'execution=' + execution.getId() +
\r
102 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
103 logDebug('Entered ' + method, isDebugLogEnabled)
\r
106 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
108 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
109 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
110 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
112 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "?depth=1"
\r
114 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
\r
115 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
\r
117 RESTConfig config = new RESTConfig(endPoint);
\r
118 def responseData = ''
\r
119 def aaiRequestId = UUID.randomUUID().toString()
\r
120 RESTClient client = new RESTClient(config).
\r
121 addHeader('X-TransactionId', aaiRequestId).
\r
122 addHeader('X-FromAppId', 'MSO').
\r
123 addHeader('Content-Type', 'application/xml').
\r
124 addHeader('Accept','application/xml');
\r
125 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
\r
126 client.addAuthorizationHeader(basicAuthCred)
\r
128 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
\r
129 APIResponse response = client.httpGet()
\r
130 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpGet to AAI")
\r
132 responseData = response.getResponseBodyAsString()
\r
133 execution.setVariable('PUAAIVfMod_getVnfResponseCode', response.getStatusCode())
\r
134 execution.setVariable('PUAAIVfMod_getVnfResponse', responseData)
\r
136 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
\r
137 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
\r
139 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
140 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
141 } catch (Exception ex) {
\r
142 ex.printStackTrace()
\r
143 logDebug('Exception occurred while executing AAI GET:' + ex.getMessage(), isDebugLogEnabled)
\r
144 execution.setVariable('PUAAIVfMod_getVnfResponseCode', 500)
\r
145 execution.setVariable('PUAAIVfMod_getVnfResponse', 'AAI GET Failed:' + ex.getMessage())
\r
147 logDebug('Exited ' + method, isDebugLogEnabled)
\r
148 } catch (BpmnError e) {
\r
150 } catch (Exception e) {
\r
151 logError('Caught exception in ' + method, e)
\r
152 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getGenericVnf(): ' + e.getMessage())
\r
157 * Validate the VF Module. That is, confirm that a VF Module with the input VF Module ID
\r
158 * exists in the retrieved Generic VNF. Then, check to make sure that if that VF Module
\r
159 * is the base VF Module and it's not the only VF Module for this Generic VNF, that we're not
\r
160 * attempting to delete it.
\r
162 * @param execution The flow's execution instance.
\r
164 public void validateVfModule(Execution execution) {
\r
165 def method = getClass().getSimpleName() + '.validateVfModule(' +
\r
166 'execution=' + execution.getId() +
\r
168 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
169 logDebug('Entered ' + method, isDebugLogEnabled)
\r
172 def genericVnf = execution.getVariable('PUAAIVfMod_getVnfResponse')
\r
173 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
174 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
\r
175 def vnfName = getNodeTextForce(genericVnf, 'vnf-name')
\r
176 execution.setVariable('PUAAIVfMod_vnfName', vnfName)
\r
177 def VfModule vfModule = findVfModule(genericVnf, vfModuleId)
\r
178 if (vfModule == null) {
\r
179 def String msg = 'VF Module \'' + vfModuleId + '\' does not exist in Generic VNF \'' + vnfId + '\''
\r
180 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
\r
181 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
183 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
\r
184 if (isDebugLogEnabled) {
\r
185 logDebug('VF Module \'' + vfModuleId + '\': isBaseVfModule=' + vfModule.isBaseVfModule() +
\r
186 ', isOnlyVfModule=' + vfModule.isOnlyVfModule() + ', new orchestration-status=' + orchestrationStatus,
\r
189 if (vfModule.isBaseVfModule() && !vfModule.isOnlyVfModule() && orchestrationStatus.equals('pending-delete')) {
\r
190 def String msg = 'Orchestration status for VF Module \'' + vfModuleId +
\r
191 '\' 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
192 execution.setVariable('PUAAIVfMod_vfModuleValidationError', msg)
\r
193 execution.setVariable('PUAAIVfMod_vfModuleOK', false)
\r
195 execution.setVariable('PUAAIVfMod_vfModule', vfModule)
\r
196 execution.setVariable('PUAAIVfMod_vfModuleOK', true)
\r
200 logDebug('Exited ' + method, isDebugLogEnabled)
\r
201 } catch (BpmnError e) {
\r
203 } catch (Exception e) {
\r
204 logError('Caught exception in ' + method, e)
\r
205 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in validateVfModule(): ' + e.getMessage())
\r
210 * Construct and send a PATCH request to AAI to update the VF Module.
\r
212 * @param execution The flow's execution instance.
\r
214 public void updateVfModule(Execution execution) {
\r
215 def method = getClass().getSimpleName() + '.updateVfModule(' +
\r
216 'execution=' + execution.getId() +
\r
218 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
219 logDebug('Entered ' + method, isDebugLogEnabled)
\r
222 // Construct payload
\r
223 def VfModule vfModule = (VfModule) execution.getVariable('PUAAIVfMod_vfModule')
\r
224 def Node newVfModuleNode = vfModule.getNode().clone()
\r
225 def orchestrationStatus = execution.getVariable('PUAAIVfMod_orchestrationStatus')
\r
226 def Node orchestrationStatusNode = utils.getChildNode(newVfModuleNode, 'orchestration-status')
\r
227 if (orchestrationStatusNode == null) {
\r
228 // Node doesn't exist, this should never happen, right?
\r
229 new Node(newVfModuleNode, 'orchestration-status', orchestrationStatus)
\r
231 // Node already exists, just give it a new value
\r
232 orchestrationStatusNode.setValue(orchestrationStatus)
\r
234 def VfModule newVfModule = new VfModule(newVfModuleNode, vfModule.isOnlyVfModule())
\r
235 //def payload = utils.nodeToString(newVfModuleNode)
\r
237 // Construct endpoint
\r
238 def vnfId = execution.getVariable('PUAAIVfMod_vnfId')
\r
239 def vfModuleId = execution.getVariable('PUAAIVfMod_vfModuleId')
\r
242 "vf-module-id": "${vfModuleId}",
\r
243 "orchestration-status": "${orchestrationStatus}"
\r
246 utils.logAudit("VfModule payload : " + payload)
\r
248 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
249 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
250 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
252 String endPoint = execution.getVariable("URN_aai_endpoint") + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") + "/vf-modules/vf-module/" + UriUtils.encode(vfModuleId, "UTF-8")
\r
253 utils.logAudit("PrepareUpdateAAIVfModule: AAI endPoint : " + endPoint)
\r
254 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
\r
256 RESTConfig config = new RESTConfig(endPoint);
\r
257 def responseData = ''
\r
258 def aaiRequestId = UUID.randomUUID().toString()
\r
259 RESTClient client = new RESTClient(config).
\r
260 addHeader('X-TransactionId', aaiRequestId).
\r
261 addHeader('X-FromAppId', 'MSO').
\r
262 addHeader('Content-Type', 'application/merge-patch+json').
\r
263 addHeader('Accept','application/json');
\r
264 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
\r
265 client.addAuthorizationHeader(basicAuthCred)
\r
267 logDebug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
\r
268 APIResponse response = client.httpPatch(payload)
\r
269 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
\r
270 utils.logAudit("PrepareUpdateAAIVfModule: - invoking httpPatch to AAI")
\r
272 responseData = response.getResponseBodyAsString()
\r
273 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
\r
274 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', responseData)
\r
275 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
276 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
277 utils.logAudit("PrepareUpdateAAIVfModule: AAI Response : " + responseData)
\r
278 utils.logAudit("PrepareUpdateAAIVfModule: AAI ResponseCode : " + response.getStatusCode())
\r
280 // Set the output for this flow. The updated VfModule is an output, the generic VNF name, and for
\r
281 // backward compatibilty, the heat-stack-id is an output
\r
282 execution.setVariable('PUAAIVfMod_outVfModule', newVfModule)
\r
283 def vnfName = execution.getVariable('PUAAIVfMod_vnfName')
\r
284 logDebug('Output PUAAIVfMod_vnfName set to ' + vnfName, isDebugLogEnabled)
\r
285 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
\r
286 execution.setVariable('WorkflowResponse', newVfModule)
\r
287 logDebug('Output PUAAIVfMod_outVfModule set for VF Module Id \'' + newVfModule.getElementText('vf-module-id') + '\'', isDebugLogEnabled)
\r
288 def heatStackId = newVfModule.getElementText('heat-stack-id')
\r
289 execution.setVariable('PUAAIVfMod_heatStackId', heatStackId)
\r
290 logDebug('Output PUAAIVfMod_heatStackId set to \'' + heatStackId + '\'', isDebugLogEnabled)
\r
291 } catch (Exception ex) {
\r
292 ex.printStackTrace()
\r
293 logDebug('Exception occurred while executing AAI PUT:' + ex.getMessage(), isDebugLogEnabled)
\r
294 execution.setVariable('PUAAIVfMod_updateVfModuleResponseCode', 500)
\r
295 execution.setVariable('PUAAIVfMod_updateVfModuleResponse', 'AAI PATCH Failed:' + ex.getMessage())
\r
297 logDebug('Exited ' + method, isDebugLogEnabled)
\r
298 } catch (BpmnError e) {
\r
300 } catch (Exception e) {
\r
301 logError('Caught exception in ' + method, e)
\r
302 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
\r
307 * Generates a WorkflowException if the AAI query returns a response code other than 200.
\r
309 * @param execution The flow's execution instance.
\r
311 public void handleVnfNotFound(Execution execution) {
\r
312 def method = getClass().getSimpleName() + '.handleVnfNotFound(' +
\r
313 'execution=' + execution.getId() +
\r
315 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
316 logDebug('Entered ' + method, isDebugLogEnabled)
\r
318 logError('Error occurred attempting to query AAI, Response Code ' +
\r
319 execution.getVariable('PUAAIVfMod_getVnfResponseCode') + ', Error Response ' +
\r
320 execution.getVariable('PUAAIVfMod_getVnfResponse'))
\r
321 String processKey = getProcessKey(execution);
\r
322 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
323 execution.getVariable('PUAAIVfMod_getVnfResponse'))
\r
324 execution.setVariable('WorkflowException', exception)
\r
326 logDebug('Exited ' + method, isDebugLogEnabled)
\r
330 * Generates a WorkflowException if the VF Module does not pass validation.
\r
332 * @param execution The flow's execution instance.
\r
334 public void handleVfModuleValidationError(Execution execution) {
\r
335 def method = getClass().getSimpleName() + '.handleVfModuleValidationError(' +
\r
336 'execution=' + execution.getId() +
\r
338 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
339 logDebug('Entered ' + method, isDebugLogEnabled)
\r
341 def String errorMsg = 'VF Module validation error: ' + execution.getVariable('PUAAIVfMod_vfModuleValidationError')
\r
343 utils.logAudit("PrepareUpdateAAIVfModule: Error Message : " + errorMsg)
\r
345 String processKey = getProcessKey(execution);
\r
346 WorkflowException exception = new WorkflowException(processKey, 5000, errorMsg)
\r
347 execution.setVariable('WorkflowException', exception)
\r
349 logDebug('Exited ' + method, isDebugLogEnabled)
\r
353 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
\r
355 * @param execution The flow's execution instance.
\r
357 public void handleUpdateVfModuleFailure(Execution execution) {
\r
358 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
\r
359 'execution=' + execution.getId() +
\r
361 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
362 logDebug('Entered ' + method, isDebugLogEnabled)
\r
364 logError('Error occurred attempting to update VF Module in AAI, Response Code ' +
\r
365 execution.getVariable('PUAAIVfMod_updateVfModuleResponseCode') + ', Error Response ' +
\r
366 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
\r
367 String processKey = getProcessKey(execution);
\r
368 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
369 execution.getVariable('PUAAIVfMod_updateVfModuleResponse'))
\r
370 execution.setVariable('WorkflowException', exception)
\r
372 logDebug('Exited ' + method, isDebugLogEnabled)
\r