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.springframework.web.util.UriUtils
\r
30 public class UpdateAAIVfModule extends AbstractServiceTaskProcessor {
\r
32 private XmlParser xmlParser = new XmlParser()
\r
33 ExceptionUtil exceptionUtil = new ExceptionUtil()
\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', 'UAAIVfMod_')
\r
42 execution.setVariable('UAAIVfMod_vnfId', null)
\r
43 execution.setVariable('UAAIVfMod_vfModuleId', null)
\r
44 execution.setVariable('UAAIVfMod_orchestrationStatus', null)
\r
45 execution.setVariable('UAAIVfMod_heatStackId', null)
\r
46 execution.setVariable('UAAIVfMod_volumeGroupId', null)
\r
47 execution.setVariable('UAAIVfMod_getVfModuleResponseCode' ,null)
\r
48 execution.setVariable('UAAIVfMod_getVfModuleResponse', '')
\r
49 execution.setVariable('UAAIVfMod_updateVfModuleResponseCode', null)
\r
50 execution.setVariable('UAAIVfMod_updateVfModuleResponse', '')
\r
54 * Check for missing elements in the received request.
\r
56 * @param execution The flow's execution instance.
\r
58 public void preProcessRequest(Execution execution) {
\r
59 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
60 'execution=' + execution.getId() +
\r
62 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
63 logDebug('Entered ' + method, isDebugLogEnabled)
\r
66 def xml = execution.getVariable('UpdateAAIVfModuleRequest')
\r
67 logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
\r
68 utils.logAudit("UpdateAAIVfModule Request XML: " + xml)
\r
69 initProcessVariables(execution)
\r
71 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
\r
72 execution.setVariable('UAAIVfMod_vnfId', vnfId)
\r
74 def vfModuleId = getRequiredNodeText(execution, xml,'vf-module-id')
\r
75 execution.setVariable('UAAIVfMod_vfModuleId', vfModuleId)
\r
77 logDebug('Exited ' + method, isDebugLogEnabled)
\r
78 } catch (BpmnError e) {
\r
80 } catch (Exception e) {
\r
81 logError('Caught exception in ' + method, e)
\r
82 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
\r
87 * Using the received vnfId and vfModuleId, query AAI to get the corresponding VF Module.
\r
88 * A 200 response is expected with the VF Module in the response body.
\r
90 * @param execution The flow's execution instance.
\r
92 public void getVfModule(Execution execution) {
\r
93 def method = getClass().getSimpleName() + '.getVfModule(' +
\r
94 'execution=' + execution.getId() +
\r
96 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
97 logDebug('Entered ' + method, isDebugLogEnabled)
\r
100 def vnfId = execution.getVariable('UAAIVfMod_vnfId')
\r
101 def vfModuleId = execution.getVariable('UAAIVfMod_vfModuleId')
\r
103 // Construct endpoint
\r
104 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
105 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
106 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
107 String endPoint = execution.getVariable('URN_aai_endpoint') + aai_uri + '/' + UriUtils.encode(vnfId, "UTF-8") + '/vf-modules/vf-module/' + UriUtils.encode(vfModuleId, "UTF-8")
\r
110 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
\r
111 utils.logAudit("UpdateAAIVfModule sending GET to AAI endpoint: " + endPoint)
\r
113 APIResponse response = aaiUriUtil.executeAAIGetCall(execution, endPoint)
\r
114 def responseData = response.getResponseBodyAsString()
\r
115 execution.setVariable('UAAIVfMod_getVfModuleResponseCode', response.getStatusCode())
\r
116 execution.setVariable('UAAIVfMod_getVfModuleResponse', responseData)
\r
117 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
118 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
119 utils.logAudit("UpdateAAIVfModule response data: " + responseData)
\r
120 } catch (Exception ex) {
\r
121 ex.printStackTrace()
\r
122 logDebug('Exception occurred while executing AAI GET:' + ex.getMessage(),isDebugLogEnabled)
\r
123 execution.setVariable('UAAIVfMod_getVfModuleResponseCode', 500)
\r
124 execution.setVariable('UAAIVfMod_getVfModuleResponse', 'AAI GET Failed:' + ex.getMessage())
\r
126 logDebug('Exited ' + method, isDebugLogEnabled)
\r
127 } catch (BpmnError e) {
\r
129 } catch (Exception e) {
\r
130 logError('Caught exception in ' + method, e)
\r
131 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVfModule(): ' + e.getMessage())
\r
136 * Construct and send a PATCH request to AAI to update the VF Module.
\r
138 * @param execution The flow's execution instance.
\r
140 public void updateVfModule(Execution execution) {
\r
141 def method = getClass().getSimpleName() + '.updateVfModule(' +
\r
142 'execution=' + execution.getId() +
\r
144 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
145 logDebug('Entered ' + method, isDebugLogEnabled)
\r
148 def vnfId = execution.getVariable('UAAIVfMod_vnfId')
\r
149 def vfModuleId = execution.getVariable('UAAIVfMod_vfModuleId')
\r
150 def vfModule = execution.getVariable('UAAIVfMod_getVfModuleResponse')
\r
151 def origRequest = execution.getVariable('UpdateAAIVfModuleRequest')
\r
152 def Node vfModuleNode = xmlParser.parseText(vfModule)
\r
154 utils.logAudit("UpdateAAIVfModule request: " + origRequest)
\r
155 // Confirm resource-version is in retrieved VF Module
\r
156 if (utils.getChildNode(vfModuleNode, 'resource-version') == null) {
\r
157 def msg = 'Can\'t update VF Module ' + vfModuleId + ' since \'resource-version\' is missing'
\r
159 throw new Exception(msg)
\r
162 // TEMPORARY!!! Disable Volume Group Check
\r
163 // Check volume-group-id conditions
\r
164 //def checkVgiResult = checkVolumeGroupId(origRequest, vfModuleNode, isDebugLogEnabled)
\r
165 //if (checkVgiResult != null) {
\r
166 // def msg = 'Can\'t update VF Module ' + vfModuleId + ': ' + checkVgiResult
\r
168 // throw new Exception(msg)
\r
171 // Handle persona-model-id/persona-model-version
\r
172 def boolean doPersonaModelVersion = true
\r
173 def String newPersonaModelId = utils.getNodeText1(origRequest, 'persona-model-id')
\r
174 def String newPersonaModelVersion = utils.getNodeText1(origRequest, 'persona-model-version')
\r
175 if ((newPersonaModelId == null) || (newPersonaModelVersion == null)) {
\r
176 doPersonaModelVersion = false
\r
178 // Confirm "new" persona-model-id is same as "current" persona-model-id
\r
179 def String currPersonaModelId = utils.getChildNodeText(vfModuleNode, 'model-invariant-id')
\r
180 if (currPersonaModelId == null) {
\r
181 // check the old attribute name
\r
182 currPersonaModelId = utils.getChildNodeText(vfModuleNode, 'model-version-id')
\r
184 if (currPersonaModelId == null) {
\r
185 currPersonaModelId = ''
\r
187 if (!newPersonaModelId.equals(currPersonaModelId)) {
\r
188 def msg = 'Can\'t update VF Module ' + vfModuleId + ' since there is \'persona-model-id\' mismatch between the current and new values'
\r
190 throw new Exception(msg)
\r
194 // Construct payload
\r
195 String orchestrationStatusEntry = updateVfModuleNode(origRequest, vfModuleNode, 'orchestration-status')
\r
196 String heatStackIdEntry = updateVfModuleNode(origRequest, vfModuleNode, 'heat-stack-id')
\r
197 String personaModelVersionEntry = ""
\r
198 if (doPersonaModelVersion) {
\r
199 personaModelVersionEntry = updateVfModuleNode(origRequest, vfModuleNode, 'persona-model-version')
\r
201 String contrailServiceInstanceFqdnEntry = updateVfModuleNode(origRequest, vfModuleNode, 'contrail-service-instance-fqdn')
\r
203 { ${orchestrationStatusEntry}
\r
204 ${heatStackIdEntry}
\r
205 ${personaModelVersionEntry}
\r
206 ${contrailServiceInstanceFqdnEntry}
\r
207 "vf-module-id": "${vfModuleId}"
\r
212 // Construct endpoint
\r
213 AaiUtil aaiUriUtil = new AaiUtil(this)
\r
214 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
\r
215 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
\r
216 String endPoint = execution.getVariable('URN_aai_endpoint') + aai_uri + '/' + UriUtils.encode(vnfId, "UTF-8") + '/vf-modules/vf-module/' + UriUtils.encode(vfModuleId, "UTF-8")
\r
219 logDebug('sending PATCH to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
\r
220 utils.logAudit("Sending PATCH to AAI endpoint: " + endPoint)
\r
222 APIResponse response = aaiUriUtil.executeAAIPatchCall(execution, endPoint, payload)
\r
223 def responseData = response.getResponseBodyAsString()
\r
224 execution.setVariable('UAAIVfMod_updateVfModuleResponseCode', response.getStatusCode())
\r
225 execution.setVariable('UAAIVfMod_updateVfModuleResponse', responseData)
\r
226 utils.logAudit("UpdateAAIVfModule Response data: " + responseData)
\r
227 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
\r
228 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
\r
229 } catch (Exception ex) {
\r
230 ex.printStackTrace()
\r
231 logDebug('Exception occurred while executing AAI PATCH:' + ex.getMessage(),isDebugLogEnabled)
\r
232 execution.setVariable('UAAIVfMod_updateVfModuleResponseCode', 500)
\r
233 execution.setVariable('UAAIVfMod_updateVfModuleResponse', 'AAI PATCH Failed:' + ex.getMessage())
\r
235 logDebug('Exited ' + method, isDebugLogEnabled)
\r
236 } catch (BpmnError e) {
\r
238 } catch (Exception e) {
\r
239 logError('Caught exception in ' + method, e)
\r
240 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in updateVfModule(): ' + e.getMessage())
\r
245 * Sets up json attributes for PATCH request for Update
\r
247 * @param origRequest Incoming update request with VF Module elements to be updated.
\r
248 * @param vfModule Current VF Module retrieved from AAI.
\r
249 * @param element Name of element to be inserted.
\r
251 private String updateVfModuleNode(String origRequest, Node vfModuleNode, String elementName) {
\r
253 if (!utils.nodeExists(origRequest, elementName)) {
\r
256 def elementValue = utils.getNodeText(origRequest, elementName)
\r
258 if (elementValue.equals('DELETE')) {
\r
259 // Set the element being deleted to null
\r
260 return """"${elementName}": null,"""
\r
263 return """"${elementName}": "${elementValue}","""
\r
269 * Check the Volume Group ID from the incoming update request against the Volume Group ID from the
\r
270 * given VF Module. If they are equal or if they are both 'null', then that is acceptable and 'null'
\r
271 * is returned. Otherwise a message describing how the values are unacceptable/incompatible is returned.
\r
273 * @param origRequest Incoming update request with VF Module elements to be updated.
\r
274 * @param vfModuleNode VF Module (as a Node) retrieved from AAI.
\r
275 * @param isDebugLogEnabled Is DEBUG log enabled?
\r
276 * @return 'null' if the Volume Group IDs are acceptable. Otherwise return a message describing how the
\r
277 * values are unacceptable/incompatible.
\r
279 private String checkVolumeGroupId(String origRequest, Node vfModuleNode, String isDebugLogEnabled) {
\r
280 def requestVolumeGroupId = utils.getNodeText1(origRequest, 'volume-group-id')
\r
281 def currVolumeGroupId = getCurrVolumeGroupId(vfModuleNode)
\r
283 logDebug('Check volume-group-id: volume-group-id in original request is \'' + requestVolumeGroupId +
\r
284 '\', volume-group-id from VF Module is \'' + currVolumeGroupId + '\'', isDebugLogEnabled)
\r
288 if (requestVolumeGroupId == null) {
\r
289 if (currVolumeGroupId == null) {
\r
292 result = 'Cannot detach a volume group from an existing VF Module'
\r
295 if (currVolumeGroupId == null) {
\r
296 result = 'Cannot add a volume gruop to an existing VF Module'
\r
298 if (!requestVolumeGroupId.equals(currVolumeGroupId)) {
\r
299 result = 'Cannot change the volume group on an existing VF Module'
\r
308 * Find and return the value of the Volume Group ID for the specified VF Module. If
\r
309 * the value of the Volume Group ID cannot be found for any reason, 'null' is returned.
\r
311 * @param vfModuleNode VF Module (as a Node) retrieved from AAI.
\r
312 * @return the value of the Volume Group ID for the specified VF Module. If the
\r
313 * value of the Volume Group ID cannot be found for any reason, 'null' is returned.
\r
315 private String getCurrVolumeGroupId(Node vfModuleNode) {
\r
316 def Node relationshipList = utils.getChildNode(vfModuleNode, 'relationship-list')
\r
317 if (relationshipList == null) {
\r
320 def NodeList relationships = utils.getIdenticalChildren(relationshipList, 'relationship')
\r
321 for (Node relationshipNode in relationships) {
\r
322 def String relatedTo = utils.getChildNodeText(relationshipNode, 'related-to')
\r
323 if ((relatedTo != null) && relatedTo.equals('volume-group')) {
\r
324 def NodeList relationshipDataList = utils.getIdenticalChildren(relationshipNode, 'relationship-data')
\r
325 for (Node relationshipDataNode in relationshipDataList) {
\r
326 def String relationshipKey = utils.getChildNodeText(relationshipDataNode, 'relationship-key')
\r
327 if ((relationshipKey != null) && relationshipKey.equals('volume-group.volume-group-id')) {
\r
328 return utils.getChildNodeText(relationshipDataNode, 'relationship-value')
\r
337 * Generates a WorkflowException if the AAI query returns a response code other than 200.
\r
339 * @param execution The flow's execution instance.
\r
341 public void handleAAIQueryFailure(Execution execution) {
\r
342 def method = getClass().getSimpleName() + '.handleAAIQueryFailure(' +
\r
343 'execution=' + execution.getId() +
\r
345 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
346 logDebug('Entered ' + method, isDebugLogEnabled)
\r
348 logError('Error occurred attempting to query AAI, Response Code ' +
\r
349 execution.getVariable('UAAIVfMod_getVfModuleResponseCode') + ', Error Response ' +
\r
350 execution.getVariable('UAAIVfMod_getVfModuleResponse'))
\r
351 String processKey = getProcessKey(execution);
\r
352 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
353 execution.getVariable('UAAIVfMod_getVfModuleResponse'))
\r
354 execution.setVariable('WorkflowException', exception)
\r
355 utils.logAudit("UpdateAAIVfModule query failure: " + exception.getErrorMessage())
\r
356 logDebug('Exited ' + method, isDebugLogEnabled)
\r
360 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
\r
362 * @param execution The flow's execution instance.
\r
364 public void handleUpdateVfModuleFailure(Execution execution) {
\r
365 def method = getClass().getSimpleName() + '.handleUpdateVfModuleFailure(' +
\r
366 'execution=' + execution.getId() +
\r
368 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
369 logDebug('Entered ' + method, isDebugLogEnabled)
\r
371 logError('Error occurred attempting to update VF Module in AAI, Response Code ' +
\r
372 execution.getVariable('UAAIVfMod_updateVfModuleResponseCode') + ', Error Response ' +
\r
373 execution.getVariable('UAAIVfMod_updateVfModuleResponse'))
\r
374 String processKey = getProcessKey(execution);
\r
375 WorkflowException exception = new WorkflowException(processKey, 5000,
\r
376 execution.getVariable('UAAIVfMod_updateVfModuleResponse'))
\r
377 execution.setVariable('WorkflowException', exception)
\r
379 utils.logAudit("UpdateAAIVfModule failure: " + exception.getErrorMessage())
\r
380 logDebug('Exited ' + method, isDebugLogEnabled)
\r