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 com.att.bpm.scripts
23 import groovy.util.Node
24 import groovy.util.XmlParser;
25 import groovy.xml.QName
27 import java.io.Serializable;
29 import org.camunda.bpm.engine.delegate.BpmnError
30 import org.camunda.bpm.engine.runtime.Execution
31 import org.springframework.web.util.UriUtils
33 import org.openecomp.mso.rest.APIResponse
34 import org.openecomp.mso.rest.RESTClient
35 import org.openecomp.mso.rest.RESTConfig
36 import org.openecomp.mso.bpmn.core.RollbackData
37 import org.openecomp.mso.bpmn.core.WorkflowException
40 public class UpdateAAIGenericVnf extends AbstractServiceTaskProcessor {
42 private XmlParser xmlParser = new XmlParser()
45 * Initialize the flow's variables.
47 * @param execution The flow's execution instance.
49 public void initProcessVariables(Execution execution) {
50 execution.setVariable('prefix', 'UAAIGenVnf_')
51 execution.setVariable('UAAIGenVnf_vnfId', null)
52 execution.setVariable('UAAIGenVnf_personaModelId', null)
53 execution.setVariable('UAAIGenVnf_personaModelVersion', null)
54 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode' ,null)
55 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', '')
56 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', null)
57 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', '')
61 * Check for missing elements in the received request.
63 * @param execution The flow's execution instance.
65 public void preProcessRequest(Execution execution) {
66 def method = getClass().getSimpleName() + '.preProcessRequest(' +
67 'execution=' + execution.getId() +
69 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
70 logDebug('Entered ' + method, isDebugLogEnabled)
73 def xml = execution.getVariable('UpdateAAIGenericVnfRequest')
74 logDebug('Received request xml:\n' + xml, isDebugLogEnabled)
75 initProcessVariables(execution)
77 def vnfId = getRequiredNodeText(execution, xml,'vnf-id')
78 execution.setVariable('UAAIGenVnf_vnfId', vnfId)
80 def personaModelId = getRequiredNodeText(execution, xml,'persona-model-id')
81 execution.setVariable('UAAIGenVnf_personaModelId', personaModelId)
83 def personaModelVersion = getRequiredNodeText(execution, xml,'persona-model-version')
84 execution.setVariable('UAAIGenVnf_personaModelVersion', personaModelVersion)
86 logDebug('Exited ' + method, isDebugLogEnabled)
87 } catch (BpmnError e) {
89 } catch (Exception e) {
90 logError('Caught exception in ' + method, e)
91 createWorkflowException(execution, 1002, 'Error in preProcessRequest(): ' + e.getMessage())
96 * Using the received vnfId, query AAI to get the corresponding Generic VNF.
97 * A 200 response is expected with the VF Module in the response body.
99 * @param execution The flow's execution instance.
101 public void getGenericVnf(Execution execution) {
102 def method = getClass().getSimpleName() + '.getGenericVnf(' +
103 'execution=' + execution.getId() +
105 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
106 logDebug('Entered ' + method, isDebugLogEnabled)
109 def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
111 // Construct endpoint
112 AaiUtil aaiUriUtil = new AaiUtil(this)
113 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
114 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
115 String endPoint = execution.getVariable('URN_aai_endpoint') + aai_uri + '/' + UriUtils.encode(vnfId, "UTF-8")
117 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
120 RESTConfig config = new RESTConfig(endPoint);
121 def responseData = ''
122 def aaiRequestId = UUID.randomUUID().toString()
123 RESTClient client = new RESTClient(config).
124 addHeader('X-TransactionId', aaiRequestId).
125 addHeader('X-FromAppId', 'MSO').
126 addHeader('Content-Type', 'application/xml').
127 addHeader('Accept','application/xml');
128 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
129 client.addAuthorizationHeader(basicAuthCred)
132 logDebug('sending GET to AAI endpoint \'' + endPoint + '\'', isDebugLogEnabled)
133 APIResponse response = client.httpGet()
135 responseData = response.getResponseBodyAsString()
136 execution.setVariable('UAAIGenVnf_getGenericVnfResponseCode', response.getStatusCode())
137 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', responseData)
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('UAAIGenVnf_getGenericVnfResponseCode', 500)
144 execution.setVariable('UAAIGenVnf_getGenericVnfResponse', '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 * Construct and send a PUT request to AAI to update the Generic VNF.
158 * @param execution The flow's execution instance.
160 public void updateGenericVnf(Execution execution) {
161 def method = getClass().getSimpleName() + '.updateGenericVnf(' +
162 'execution=' + execution.getId() +
164 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
165 logDebug('Entered ' + method, isDebugLogEnabled)
168 def vnfId = execution.getVariable('UAAIGenVnf_vnfId')
169 def genericVnf = execution.getVariable('UAAIGenVnf_getGenericVnfResponse')
170 def origRequest = execution.getVariable('UpdateAAIGenericVnfRequest')
172 // Confirm resource-version is in retrieved Generic VNF
173 def Node genericVnfNode = xmlParser.parseText(genericVnf)
174 if (utils.getChildNode(genericVnfNode, 'resource-version') == null) {
175 def msg = 'Can\'t update Generic VNF ' + vnfId + ' since \'resource-version\' is missing'
177 throw new Exception(msg)
180 // Handle persona-model-id/persona-model-version
181 def String newPersonaModelId = execution.getVariable('UAAIGenVnf_personaModelId')
182 def String newPersonaModelVersion = execution.getVariable('UAAIGenVnf_personaModelVersion')
184 // Confirm "new" persona-model-id is same as "current" persona-model-id
185 def Node currPersonaModelIdNode = utils.getChildNode(genericVnfNode, 'persona-model-id')
186 def String currPersonaModelId = ''
187 if (currPersonaModelIdNode != null) {
188 currPersonaModelId = currPersonaModelIdNode.text()
190 if (!newPersonaModelId.equals(currPersonaModelId)) {
191 def msg = 'Can\'t update Generic VNF ' + vnfId + ' since there is \'persona-model-id\' mismatch between the current and new values'
193 throw new Exception(msg)
197 updateGenericVnfNode(origRequest, genericVnfNode, 'persona-model-version')
198 def payload = utils.nodeToString(genericVnfNode)
200 // Construct endpoint
201 AaiUtil aaiUriUtil = new AaiUtil(this)
202 def aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
203 logDebug('AAI URI is: ' + aai_uri, isDebugLogEnabled)
204 String endPoint = execution.getVariable('URN_aai_endpoint') + aai_uri + '/' + UriUtils.encode(vnfId, "UTF-8")
206 String basicAuthCred = utils.getBasicAuth(execution.getVariable("URN_aai_auth"),execution.getVariable("URN_mso_msoKey"))
209 RESTConfig config = new RESTConfig(endPoint);
210 def responseData = ''
211 def aaiRequestId = UUID.randomUUID().toString()
212 RESTClient client = new RESTClient(config).
213 addHeader('X-TransactionId', aaiRequestId).
214 addHeader('X-FromAppId', 'MSO').
215 addHeader('Content-Type', 'application/xml').
216 addHeader('Accept','application/xml');
217 if (basicAuthCred != null && !"".equals(basicAuthCred)) {
218 client.addAuthorizationHeader(basicAuthCred)
221 logDebug('sending PUT to AAI endpoint \'' + endPoint + '\'' + 'with payload \n' + payload, isDebugLogEnabled)
222 APIResponse response = client.httpPut(payload)
224 responseData = response.getResponseBodyAsString()
225 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', response.getStatusCode())
226 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', responseData)
227 logDebug('Response code:' + response.getStatusCode(), isDebugLogEnabled)
228 logDebug('Response:' + System.lineSeparator() + responseData, isDebugLogEnabled)
229 } catch (Exception ex) {
231 logDebug('Exception occurred while executing AAI PUT:' + ex.getMessage(),isDebugLogEnabled)
232 execution.setVariable('UAAIGenVnf_updateGenericVnfResponseCode', 500)
233 execution.setVariable('UAAIGenVnf_updateGenericVnfResponse', 'AAI PUT Failed:' + ex.getMessage())
235 logDebug('Exited ' + method, isDebugLogEnabled)
236 } catch (BpmnError e) {
238 } catch (Exception e) {
239 logError('Caught exception in ' + method, e)
240 createWorkflowException(execution, 1002, 'Error in updateGenericVnf(): ' + e.getMessage())
245 * Insert a new Node, replace the value of an existing Node, or delete an existing Node in the current
246 * Generic VNF Node, as necessary.
248 * If the Node with the same name already exists in current Generic VNF, but is not being updated, then do
249 * nothing. If the element is being updated and it already exists in the current Generic VNF, then check
250 * the value specified in the original request. If the value is 'DELETE', remove that Node from the
251 * current Generic VNF. Otherwise, change the value to the specified new value. If the element is
252 * being updated but doesn't exist in the current Generic VNF, and the new value is not 'DELETE', then
253 * create an appropriate new node and add it to the Generic VNF.
255 * @param origRequest Incoming update request with Generic VNF element(s) to be updated.
256 * @param genericVnf Current Generic VNF retrieved from AAI.
257 * @param element Name of element to be inserted.
259 public void updateGenericVnfNode(String origRequest, Node genericVnfNode, String elementName) {
261 if (!utils.nodeExists(origRequest, elementName)) {
264 def elementValue = utils.getNodeText(origRequest, elementName)
266 def Node childNode = utils.getChildNode(genericVnfNode, elementName)
267 if (childNode == null) {
268 if (elementValue.equals('DELETE')) {
269 // Element doesn't exist but is being deleted, so do nothing
272 // Node doesn't exist, create a new Node as a child
273 new Node(genericVnfNode, elementName, elementValue)
275 if (elementValue.equals('DELETE')) {
276 // Node exists, but should be deleted
277 genericVnfNode.remove(childNode)
279 // Node already exists, just give it a new value
280 childNode.setValue(elementValue)
286 * Generates a WorkflowException if the AAI query returns a response code other than 200.
288 * @param execution The flow's execution instance.
290 public void handleAAIQueryFailure(Execution execution) {
291 def method = getClass().getSimpleName() + '.handleAAIQueryFailure(' +
292 'execution=' + execution.getId() +
294 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
295 logDebug('Entered ' + method, isDebugLogEnabled)
297 logError('Error occurred attempting to query AAI, Response Code ' +
298 execution.getVariable('UAAIGenVnf_getGenericVnfResponseCode') + ', Error Response ' +
299 execution.getVariable('UAAIGenVnf_getGenericVnfResponse'))
300 String processKey = getProcessKey(execution);
301 WorkflowException exception = new WorkflowException(processKey, 5000,
302 execution.getVariable('UAAIGenVnf_getGenericVnfResponse'))
303 execution.setVariable('WorkflowException', exception)
305 logDebug('Exited ' + method, isDebugLogEnabled)
309 * Generates a WorkflowException if updating a VF Module in AAI returns a response code other than 200.
311 * @param execution The flow's execution instance.
313 public void handleUpdateGenericVnfFailure(Execution execution) {
314 def method = getClass().getSimpleName() + '.handleUpdateGenericVnfFailure(' +
315 'execution=' + execution.getId() +
317 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
318 logDebug('Entered ' + method, isDebugLogEnabled)
320 logError('Error occurred attempting to update Generic VNF in AAI, Response Code ' +
321 execution.getVariable('UAAIGenVnf_updateGenericVnfResponseCode') + ', Error Response ' +
322 execution.getVariable('UAAIGenVnf_updateGenericVnfResponse'))
323 String processKey = getProcessKey(execution);
324 WorkflowException exception = new WorkflowException(processKey, 5000,
325 execution.getVariable('UAAIGenVnf_updateGenericVnfResponse'))
326 execution.setVariable('WorkflowException', exception)
328 logDebug('Exited ' + method, isDebugLogEnabled)