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.onap.so.bpmn.infrastructure.scripts
23 import javax.xml.parsers.DocumentBuilder
24 import javax.xml.parsers.DocumentBuilderFactory
26 import org.camunda.bpm.engine.delegate.BpmnError
27 import org.camunda.bpm.engine.delegate.DelegateExecution
28 import org.onap.so.bpmn.common.scripts.AaiUtil
29 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
30 import org.onap.so.bpmn.common.scripts.ExceptionUtil
31 import org.onap.so.bpmn.common.scripts.MsoUtils
32 import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils
33 import org.onap.so.bpmn.common.scripts.VfModule
34 import org.onap.so.bpmn.core.UrnPropertiesReader
35 import org.onap.so.bpmn.core.WorkflowException
36 import org.onap.so.bpmn.core.json.JsonUtils
37 import org.onap.so.logger.MessageEnum
38 import org.onap.so.logger.MsoLogger
39 import org.onap.so.rest.APIResponse
40 import org.onap.so.rest.RESTClient
41 import org.onap.so.rest.RESTConfig
42 import org.springframework.web.util.UriUtils
43 import org.w3c.dom.Document
44 import org.w3c.dom.Element
45 import org.w3c.dom.Node
46 import org.w3c.dom.NodeList;
47 import org.xml.sax.InputSource
49 /* Subflow for Delete VF Module. When no DoDeleteVfModuleRequest is specified on input,
50 * functions as a building block subflow
52 * Inputs for building block interface:
54 * @param - isDebugLogEnabled
57 * @param - serviceInstanceId
58 * @param - vfModuleName O
59 * @param - vfModuleModelInfo
60 * @param - cloudConfiguration*
61 * @param - sdncVersion ("1610")
62 * @param - retainResources
66 * @param - WorkflowException
69 public class DoDeleteVfModule extends AbstractServiceTaskProcessor{
70 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, DoDeleteVfModule.class);
72 def Prefix="DoDVfMod_"
74 ExceptionUtil exceptionUtil = new ExceptionUtil()
75 JsonUtils jsonUtil = new JsonUtils()
77 public void initProcessVariables(DelegateExecution execution) {
78 execution.setVariable("prefix",Prefix)
79 execution.setVariable("DoDVfMod_contrailNetworkPolicyFqdnList", null)
80 execution.setVariable("DoDVfMod_oamManagementV4Address", null)
81 execution.setVariable("DoDVfMod_oamManagementV6Address", null)
85 // parse the incoming DELETE_VF_MODULE request for the Generic Vnf and Vf Module Ids
86 // and formulate the outgoing request for PrepareUpdateAAIVfModuleRequest
87 public void preProcessRequest(DelegateExecution execution) {
89 initProcessVariables(execution)
92 def xml = execution.getVariable("DoDeleteVfModuleRequest")
94 String vfModuleId = ""
96 if (xml == null || xml.isEmpty()) {
97 // Building Block-type request
99 // Set mso-request-id to request-id for VNF Adapter interface
100 String requestId = execution.getVariable("requestId")
101 execution.setVariable("mso-request-id", requestId)
103 String cloudConfiguration = execution.getVariable("cloudConfiguration")
104 String vfModuleModelInfo = execution.getVariable("vfModuleModelInfo")
105 String tenantId = jsonUtil.getJsonValue(cloudConfiguration, "tenantId")
106 execution.setVariable("tenantId", tenantId)
107 String cloudSiteId = jsonUtil.getJsonValue(cloudConfiguration, "lcpCloudRegionId")
108 execution.setVariable("cloudSiteId", cloudSiteId)
109 // Source is HARDCODED
110 String source = "VID"
111 execution.setVariable("source", source)
112 // SrvInstId is hardcoded to empty
113 execution.setVariable("srvInstId", "")
114 // ServiceId is hardcoded to empty
115 execution.setVariable("serviceId", "")
116 String serviceInstanceId = execution.getVariable("serviceInstanceId")
117 vnfId = execution.getVariable("vnfId")
118 vfModuleId = execution.getVariable("vfModuleId")
119 if (serviceInstanceId == null || serviceInstanceId.isEmpty()) {
120 execution.setVariable(Prefix + "serviceInstanceIdToSdnc", vfModuleId)
123 execution.setVariable(Prefix + "serviceInstanceIdToSdnc", serviceInstanceId)
126 def vfModuleModelName = jsonUtil.getJsonValue(vfModuleModelInfo, "modelName")
127 execution.setVariable("vfModuleModelName", vfModuleModelName)
129 def retainResources = execution.getVariable("retainResources")
130 if (retainResources == null) {
131 retainResources = false
133 execution.setVariable("retainResources", retainResources)
137 msoLogger.debug("DoDeleteVfModule Request: " + xml)
139 msoLogger.debug("input request xml: " + xml)
141 vnfId = utils.getNodeText(xml,"vnf-id")
142 execution.setVariable("vnfId", vnfId)
143 vfModuleId = utils.getNodeText(xml,"vf-module-id")
144 execution.setVariable("vfModuleId", vfModuleId)
145 def srvInstId = execution.getVariable("mso-service-instance-id")
146 execution.setVariable("srvInstId", srvInstId)
147 String requestId = ""
149 requestId = execution.getVariable("mso-request-id")
150 } catch (Exception ex) {
151 requestId = utils.getNodeText(xml, "request-id")
153 execution.setVariable("requestId", requestId)
154 String source = utils.getNodeText(xml, "source")
155 execution.setVariable("source", source)
156 String serviceId = utils.getNodeText(xml, "service-id")
157 execution.setVariable("serviceId", serviceId)
158 String tenantId = utils.getNodeText(xml, "tenant-id")
159 execution.setVariable("tenantId", tenantId)
161 String serviceInstanceIdToSdnc = ""
162 if (xml.contains("service-instance-id")) {
163 serviceInstanceIdToSdnc = utils.getNodeText(xml, "service-instance-id")
165 serviceInstanceIdToSdnc = vfModuleId
167 execution.setVariable(Prefix + "serviceInstanceIdToSdnc", serviceInstanceIdToSdnc)
168 String vfModuleName = utils.getNodeText(xml, "vf-module-name")
169 execution.setVariable("vfModuleName", vfModuleName)
170 String vfModuleModelName = utils.getNodeText(xml, "vf-module-model-name")
171 execution.setVariable("vfModuleModelName", vfModuleModelName)
172 String cloudSiteId = utils.getNodeText(xml, "aic-cloud-region")
173 execution.setVariable("cloudSiteId", cloudSiteId)
176 // formulate the request for PrepareUpdateAAIVfModule
177 String request = """<PrepareUpdateAAIVfModuleRequest>
178 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
179 <vf-module-id>${MsoUtils.xmlEscape(vfModuleId)}</vf-module-id>
180 <orchestration-status>pending-delete</orchestration-status>
181 </PrepareUpdateAAIVfModuleRequest>""" as String
182 msoLogger.debug("PrepareUpdateAAIVfModuleRequest :" + request)
183 msoLogger.debug("UpdateAAIVfModule Request: " + request)
184 execution.setVariable("PrepareUpdateAAIVfModuleRequest", request)
185 execution.setVariable("vfModuleFromAAI", null)
189 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, "Internal Error encountered in PreProcess method!")
193 // build a SDNC vnf-topology-operation request for the specified action
194 // (note: the action passed is expected to be 'changedelete' or 'delete')
195 public void prepSDNCAdapterRequest(DelegateExecution execution, String action) {
198 String uuid = execution.getVariable('testReqId') // for junits
200 uuid = execution.getVariable("requestId") + "-" + System.currentTimeMillis()
203 def srvInstId = execution.getVariable("srvInstId")
204 def callbackUrl = UrnPropertiesReader.getVariable("mso.workflow.sdncadapter.callback",execution)
205 String requestId = execution.getVariable("requestId")
206 String source = execution.getVariable("source")
207 String serviceId = execution.getVariable("serviceId")
208 String vnfId = execution.getVariable("vnfId")
209 String tenantId = execution.getVariable("tenantId")
210 String vfModuleId = execution.getVariable("vfModuleId")
211 String serviceInstanceIdToSdnc = execution.getVariable(Prefix + "serviceInstanceIdToSdnc")
212 String vfModuleName = execution.getVariable("vfModuleName")
213 // Get vfModuleName from AAI response if it was not specified on the request
214 if (vfModuleName == null || vfModuleName.isEmpty()) {
215 if (execution.getVariable("vfModuleFromAAI") != null) {
216 VfModule vfModuleFromAAI = execution.getVariable("vfModuleFromAAI")
217 vfModuleName = vfModuleFromAAI.getElementText("vf-module-name")
220 String vfModuleModelName = execution.getVariable("vfModuleModelName")
221 String cloudSiteId = execution.getVariable("cloudSiteId")
222 boolean retainResources = execution.getVariable("retainResources")
223 String requestSubActionString = ""
224 if (retainResources) {
225 requestSubActionString = "<request-sub-action>RetainResource</request-sub-action>"
227 String request = """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.onap/so/request/types/v1"
228 xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
229 xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
230 <sdncadapter:RequestHeader>
231 <sdncadapter:RequestId>${MsoUtils.xmlEscape(uuid)}</sdncadapter:RequestId>
232 <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(vfModuleId)}</sdncadapter:SvcInstanceId>
233 <sdncadapter:SvcAction>${MsoUtils.xmlEscape(action)}</sdncadapter:SvcAction>
234 <sdncadapter:SvcOperation>vnf-topology-operation</sdncadapter:SvcOperation>
235 <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackUrl)}</sdncadapter:CallbackUrl>
236 </sdncadapter:RequestHeader>
237 <sdncadapterworkflow:SDNCRequestData>
238 <request-information>
239 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
240 <request-action>DisconnectVNFRequest</request-action>
241 ${requestSubActionString}
242 <source>${MsoUtils.xmlEscape(source)}</source>
246 </request-information>
247 <service-information>
248 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
249 <service-type>${MsoUtils.xmlEscape(serviceId)}</service-type>
250 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceIdToSdnc)}</service-instance-id>
251 <subscriber-name>notsurewecare</subscriber-name>
252 </service-information>
253 <vnf-request-information>
254 <vnf-id>${MsoUtils.xmlEscape(vfModuleId)}</vnf-id>
255 <vnf-type>${MsoUtils.xmlEscape(vfModuleModelName)}</vnf-type>
256 <vnf-name>${MsoUtils.xmlEscape(vfModuleName)}</vnf-name>
257 <generic-vnf-id>${MsoUtils.xmlEscape(vnfId)}</generic-vnf-id>
258 <generic-vnf-name></generic-vnf-name>
259 <generic-vnf-type></generic-vnf-type>
260 <aic-cloud-region>${MsoUtils.xmlEscape(cloudSiteId)}</aic-cloud-region>
261 <tenant>${MsoUtils.xmlEscape(tenantId)}</tenant>
262 </vnf-request-information>
263 </sdncadapterworkflow:SDNCRequestData>
264 </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
266 msoLogger.debug("sdncAdapterWorkflowRequest: " + request)
267 msoLogger.debug("DoDeleteVfModule - SDNCAdapterWorkflowRequest: " + request)
268 execution.setVariable("sdncAdapterWorkflowRequest", request)
271 // parse the incoming DELETE_VF_MODULE request
272 // and formulate the outgoing VnfAdapterDeleteV1 request
273 public void prepVNFAdapterRequest(DelegateExecution execution) {
275 def requestId = UUID.randomUUID().toString()
276 def origRequestId = execution.getVariable('requestId')
277 def srvInstId = execution.getVariable("serviceInstanceId")
278 def aicCloudRegion = execution.getVariable("cloudSiteId")
279 def vnfId = execution.getVariable("vnfId")
280 def vfModuleId = execution.getVariable("vfModuleId")
281 def vfModuleStackId = execution.getVariable('DoDVfMod_heatStackId')
282 def tenantId = execution.getVariable("tenantId")
283 def messageId = execution.getVariable('requestId') + '-' +
284 System.currentTimeMillis()
285 def notificationUrl = createCallbackURL(execution, "VNFAResponse", messageId)
286 def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host",execution)
287 if ('true'.equals(useQualifiedHostName)) {
288 notificationUrl = utils.getQualifiedHostNameForCallback(notificationUrl)
292 <deleteVfModuleRequest>
293 <cloudSiteId>${MsoUtils.xmlEscape(aicCloudRegion)}</cloudSiteId>
294 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
295 <vnfId>${MsoUtils.xmlEscape(vnfId)}</vnfId>
296 <vfModuleId>${MsoUtils.xmlEscape(vfModuleId)}</vfModuleId>
297 <vfModuleStackId>${MsoUtils.xmlEscape(vfModuleStackId)}</vfModuleStackId>
298 <skipAAI>true</skipAAI>
300 <requestId>${MsoUtils.xmlEscape(origRequestId)}</requestId>
301 <serviceInstanceId>${MsoUtils.xmlEscape(srvInstId)}</serviceInstanceId>
303 <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
304 <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
305 </deleteVfModuleRequest>
308 msoLogger.debug("vnfAdapterRestV1Request: " + request)
309 msoLogger.debug("deleteVfModuleRequest: " + request)
310 execution.setVariable("vnfAdapterRestV1Request", request)
313 // parse the incoming DELETE_VF_MODULE request
314 // and formulate the outgoing UpdateAAIVfModuleRequest request
315 public void prepUpdateAAIVfModule(DelegateExecution execution) {
317 def vnfId = execution.getVariable("vnfId")
318 def vfModuleId = execution.getVariable("vfModuleId")
319 // formulate the request for UpdateAAIVfModule
320 String request = """<UpdateAAIVfModuleRequest>
321 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
322 <vf-module-id>${MsoUtils.xmlEscape(vfModuleId)}</vf-module-id>
323 <heat-stack-id>DELETE</heat-stack-id>
324 <orchestration-status>deleted</orchestration-status>
325 </UpdateAAIVfModuleRequest>""" as String
326 msoLogger.debug("UpdateAAIVfModuleRequest :" + request)
327 msoLogger.debug("UpdateAAIVfModuleRequest: " + request)
328 execution.setVariable("UpdateAAIVfModuleRequest", request)
331 // parse the incoming DELETE_VF_MODULE request
332 // and formulate the outgoing DeleteAAIVfModuleRequest request
333 public void prepDeleteAAIVfModule(DelegateExecution execution) {
336 def vnfId = execution.getVariable("vnfId")
337 def vfModuleId = execution.getVariable("vfModuleId")
338 // formulate the request for UpdateAAIVfModule
339 String request = """<DeleteAAIVfModuleRequest>
340 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
341 <vf-module-id>${MsoUtils.xmlEscape(vfModuleId)}</vf-module-id>
342 </DeleteAAIVfModuleRequest>""" as String
343 msoLogger.debug("DeleteAAIVfModuleRequest :" + request)
344 msoLogger.debug("DeleteAAIVfModuleRequest: " + request)
345 execution.setVariable("DeleteAAIVfModuleRequest", request)
348 // generates a WorkflowException if
350 public void handleDoDeleteVfModuleFailure(DelegateExecution execution) {
351 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, "AAI error occurred deleting the Generic Vnf: " + execution.getVariable("DoDVfMod_deleteGenericVnfResponse"), "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception");
352 String processKey = getProcessKey(execution);
353 WorkflowException exception = new WorkflowException(processKey, 5000,
354 execution.getVariable("DoDVfMod_deleteGenericVnfResponse"))
355 execution.setVariable("WorkflowException", exception)
358 public void sdncValidateResponse(DelegateExecution execution, String response){
360 execution.setVariable("prefix",Prefix)
362 WorkflowException workflowException = execution.getVariable("WorkflowException")
363 boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
365 SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils(this)
366 sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
368 if(execution.getVariable(Prefix + 'sdncResponseSuccess') == true){
369 msoLogger.debug("Successfully Validated SDNC Response")
371 throw new BpmnError("MSOWorkflowException")
375 public void postProcessVNFAdapterRequest(DelegateExecution execution) {
376 def method = getClass().getSimpleName() + '.postProcessVNFAdapterRequest(' +
377 'execution=' + execution.getId() +
380 msoLogger.trace('Entered ' + method)
381 execution.setVariable("prefix",Prefix)
383 msoLogger.trace("STARTED postProcessVNFAdapterRequest Process")
385 String vnfResponse = execution.getVariable("DoDVfMod_doDeleteVfModuleResponse")
386 msoLogger.debug("VNF Adapter Response is: " + vnfResponse)
387 msoLogger.debug("deleteVnfAResponse is: \n" + vnfResponse)
389 if(vnfResponse != null){
391 if(vnfResponse.contains("deleteVfModuleResponse")){
392 msoLogger.debug("Received a Good Response from VNF Adapter for DELETE_VF_MODULE Call.")
393 execution.setVariable("DoDVfMod_vnfVfModuleDeleteCompleted", true)
395 // Parse vnfOutputs for contrail network polcy FQDNs
396 if (vnfResponse.contains("vfModuleOutputs")) {
397 def vfModuleOutputsXml = utils.getNodeXml(vnfResponse, "vfModuleOutputs")
398 InputSource source = new InputSource(new StringReader(vfModuleOutputsXml));
399 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
400 docFactory.setNamespaceAware(true)
401 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
402 Document outputsXml = docBuilder.parse(source)
404 NodeList entries = outputsXml.getElementsByTagNameNS("*", "entry")
405 List contrailNetworkPolicyFqdnList = []
406 for (int i = 0; i< entries.getLength(); i++) {
407 Node node = entries.item(i)
408 if (node.getNodeType() == Node.ELEMENT_NODE) {
409 Element element = (Element) node
410 String key = element.getElementsByTagNameNS("*", "key").item(0).getTextContent()
411 if (key.endsWith("contrail_network_policy_fqdn")) {
412 String contrailNetworkPolicyFqdn = element.getElementsByTagNameNS("*", "value").item(0).getTextContent()
413 msoLogger.debug("Obtained contrailNetworkPolicyFqdn: " + contrailNetworkPolicyFqdn)
414 contrailNetworkPolicyFqdnList.add(contrailNetworkPolicyFqdn)
416 else if (key.equals("oam_management_v4_address")) {
417 String oamManagementV4Address = element.getElementsByTagNameNS("*", "value").item(0).getTextContent()
418 msoLogger.debug("Obtained oamManagementV4Address: " + oamManagementV4Address)
419 execution.setVariable(Prefix + "oamManagementV4Address", oamManagementV4Address)
421 else if (key.equals("oam_management_v6_address")) {
422 String oamManagementV6Address = element.getElementsByTagNameNS("*", "value").item(0).getTextContent()
423 msoLogger.debug("Obtained oamManagementV6Address: " + oamManagementV6Address)
424 execution.setVariable(Prefix + "oamManagementV6Address", oamManagementV6Address)
429 if (!contrailNetworkPolicyFqdnList.isEmpty()) {
430 msoLogger.debug("Setting the fqdn list")
431 execution.setVariable("DoDVfMod_contrailNetworkPolicyFqdnList", contrailNetworkPolicyFqdnList)
435 msoLogger.debug("Received a BAD Response from VNF Adapter for DELETE_VF_MODULE Call.")
436 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "VNF Adapter Error")
439 msoLogger.debug("Response from VNF Adapter is Null for DELETE_VF_MODULE Call.")
440 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Empty response from VNF Adapter")
446 msoLogger.debug("Internal Error Occured in PostProcess Method")
447 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, "Internal Error Occured in PostProcess Method")
449 msoLogger.trace("COMPLETED postProcessVnfAdapterResponse Process")
452 public void deleteNetworkPoliciesFromAAI(DelegateExecution execution) {
453 def method = getClass().getSimpleName() + '.deleteNetworkPoliciesFromAAI(' +
454 'execution=' + execution.getId() +
457 msoLogger.trace('Entered ' + method)
458 execution.setVariable("prefix", Prefix)
459 msoLogger.trace("STARTED deleteNetworkPoliciesFromAAI ")
463 List fqdnList = execution.getVariable("DoDVfMod_contrailNetworkPolicyFqdnList")
464 if (fqdnList == null) {
465 msoLogger.debug("No network policies to delete")
468 int fqdnCount = fqdnList.size()
470 execution.setVariable("DoDVfMod_networkPolicyFqdnCount", fqdnCount)
471 msoLogger.debug("DoDVfMod_networkPolicyFqdnCount - " + fqdnCount)
473 String aai_endpoint = UrnPropertiesReader.getVariable("aai.endpoint", execution)
474 AaiUtil aaiUriUtil = new AaiUtil(this)
475 String aai_uri = aaiUriUtil.getNetworkPolicyUri(execution)
478 // AII loop call over contrail network policy fqdn list
479 for (i in 0..fqdnCount-1) {
482 String fqdn = fqdnList[i]
484 // Query AAI for this network policy FQDN
486 String queryNetworkPolicyByFqdnAAIRequest = "${aai_endpoint}${aai_uri}?network-policy-fqdn=" + UriUtils.encode(fqdn, "UTF-8")
487 msoLogger.debug("AAI request endpoint: " + queryNetworkPolicyByFqdnAAIRequest)
488 msoLogger.debug("AAI request endpoint: " + queryNetworkPolicyByFqdnAAIRequest)
490 APIResponse response = aaiUriUtil.executeAAIGetCall(execution, queryNetworkPolicyByFqdnAAIRequest)
491 int returnCode = response.getStatusCode()
492 execution.setVariable("DCVFM_aaiQueryNetworkPolicyByFqdnReturnCode", returnCode)
493 msoLogger.debug(" ***** AAI query network policy Response Code, NetworkPolicy #" + counting + " : " + returnCode)
495 String aaiResponseAsString = response.getResponseBodyAsString()
497 if (isOneOf(returnCode, 200, 201)) {
498 msoLogger.debug("The return code is: " + returnCode)
499 // This network policy FQDN exists in AAI - need to delete it now
500 msoLogger.debug(aaiResponseAsString)
501 execution.setVariable("DoDVfMod_queryNetworkPolicyByFqdnAAIResponse", aaiResponseAsString)
502 msoLogger.debug("QueryAAINetworkPolicyByFQDN Success REST Response, , NetworkPolicy #" + counting + " : " + "\n" + aaiResponseAsString)
503 // Retrieve the network policy id for this FQDN
504 def networkPolicyId = utils.getNodeText(aaiResponseAsString, "network-policy-id")
505 msoLogger.debug("Deleting network-policy with network-policy-id " + networkPolicyId)
507 // Retrieve the resource version for this network policy
508 def resourceVersion = utils.getNodeText(aaiResponseAsString, "resource-version")
509 msoLogger.debug("Deleting network-policy with resource-version " + resourceVersion)
511 String delNetworkPolicyAAIRequest = "${aai_endpoint}${aai_uri}/" + UriUtils.encode(networkPolicyId, "UTF-8") +
512 "?resource-version=" + UriUtils.encode(resourceVersion, "UTF-8")
513 msoLogger.debug("AAI request endpoint: " + delNetworkPolicyAAIRequest)
514 msoLogger.debug("AAI request endpoint: " + delNetworkPolicyAAIRequest)
516 msoLogger.debug("invoking DELETE call to AAI")
517 msoLogger.debug("Sending DELETE call to AAI with Endpoint /n" + delNetworkPolicyAAIRequest)
518 APIResponse responseDel = aaiUriUtil.executeAAIDeleteCall(execution, delNetworkPolicyAAIRequest)
519 int returnCodeDel = responseDel.getStatusCode()
520 execution.setVariable("DoDVfMod_aaiDeleteNetworkPolicyReturnCode", returnCodeDel)
521 msoLogger.debug(" ***** AAI delete network policy Response Code, NetworkPolicy #" + counting + " : " + returnCodeDel)
523 if (isOneOf(returnCodeDel, 200, 201, 204)) {
524 msoLogger.debug("The return code from deleting network policy is: " + returnCodeDel)
525 // This network policy was deleted from AAI successfully
526 msoLogger.debug(" DelAAINetworkPolicy Success REST Response, , NetworkPolicy #" + counting + " : ")
530 String delErrorMessage = "Unable to delete network-policy to AAI deleteNetworkPoliciesFromAAI - " + returnCodeDel
531 msoLogger.debug(delErrorMessage)
532 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, delErrorMessage)
534 } else if (returnCode == 404) {
535 // This network policy FQDN is not in AAI. No need to delete.
536 msoLogger.debug("The return code is: " + returnCode)
537 msoLogger.debug("This network policy FQDN is not in AAI: " + fqdn)
538 msoLogger.debug("Network policy FQDN is not in AAI")
540 if (aaiResponseAsString.contains("RESTFault")) {
541 WorkflowException exceptionObject = exceptionUtil.MapAAIExceptionToWorkflowException(aaiResponseAsString, execution)
542 execution.setVariable("WorkflowException", exceptionObject)
543 throw new BpmnError("MSOWorkflowException")
547 String dataErrorMessage = "Unexpected Response from deleteNetworkPoliciesFromAAI - " + returnCode
548 msoLogger.debug(dataErrorMessage)
549 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, dataErrorMessage)
560 msoLogger.debug("No contrail network policies to query/create")
564 } catch (BpmnError e) {
567 } catch (Exception ex) {
568 String exceptionMessage = "Bpmn error encountered in DoDeletVfModule flow. deleteNetworkPoliciesFromAAI() - " + ex.getMessage()
569 msoLogger.debug(exceptionMessage)
570 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
576 * Prepare a Request for invoking the UpdateAAIGenericVnf subflow.
578 * @param execution The flow's execution instance.
580 public void prepUpdateAAIGenericVnf(DelegateExecution execution) {
581 def method = getClass().getSimpleName() + '.prepUpdateAAIGenericVnf(' +
582 'execution=' + execution.getId() +
585 msoLogger.trace('Entered ' + method)
588 def vnfId = execution.getVariable('vnfId')
589 def oamManagementV4Address = execution.getVariable(Prefix + 'oamManagementV4Address')
590 def oamManagementV6Address = execution.getVariable(Prefix + 'oamManagementV6Address')
591 def ipv4OamAddressElement = ''
592 def managementV6AddressElement = ''
594 if (oamManagementV4Address != null) {
595 ipv4OamAddressElement = '<ipv4-oam-address>' + 'DELETE' + '</ipv4-oam-address>'
598 if (oamManagementV6Address != null) {
599 managementV6AddressElement = '<management-v6-address>' + 'DELETE' + '</management-v6-address>'
603 String updateAAIGenericVnfRequest = """
604 <UpdateAAIGenericVnfRequest>
605 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
606 ${ipv4OamAddressElement}
607 ${managementV6AddressElement}
608 </UpdateAAIGenericVnfRequest>
610 updateAAIGenericVnfRequest = utils.formatXml(updateAAIGenericVnfRequest)
611 execution.setVariable(Prefix + 'updateAAIGenericVnfRequest', updateAAIGenericVnfRequest)
612 msoLogger.debug("updateAAIGenericVnfRequest : " + updateAAIGenericVnfRequest)
613 msoLogger.debug('Request for UpdateAAIGenericVnf:\n' + updateAAIGenericVnfRequest)
616 msoLogger.trace('Exited ' + method)
617 } catch (BpmnError e) {
619 } catch (Exception e) {
620 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
621 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in prepUpdateAAIGenericVnf(): ' + e.getMessage())
626 * Using the vnfId and vfModuleId provided in the inputs,
627 * query AAI to get the corresponding VF Module info.
628 * A 200 response is expected with the VF Module info in the response body,
629 * Will determine VF Module's orchestration status if one exists
631 * @param execution The flow's execution instance.
633 public void queryAAIVfModuleForStatus(DelegateExecution execution) {
635 def method = getClass().getSimpleName() + '.queryAAIVfModuleForStatus(' +
636 'execution=' + execution.getId() +
638 msoLogger.trace('Entered ' + method)
640 execution.setVariable(Prefix + 'orchestrationStatus', '')
643 def vnfId = execution.getVariable('vnfId')
644 def vfModuleId = execution.getVariable('vfModuleId')
646 AaiUtil aaiUriUtil = new AaiUtil(this)
647 String aai_uri = aaiUriUtil.getNetworkGenericVnfUri(execution)
648 msoLogger.debug('AAI URI is: ' + aai_uri)
650 String endPoint = UrnPropertiesReader.getVariable("aai.endpoint",execution) + "${aai_uri}/" + UriUtils.encode(vnfId, "UTF-8") +
651 "/vf-modules/vf-module/" + UriUtils.encode(vfModuleId, "UTF-8")
652 msoLogger.debug("AAI endPoint: " + endPoint)
655 RESTConfig config = new RESTConfig(endPoint);
656 def responseData = ''
657 def aaiRequestId = UUID.randomUUID().toString()
658 RESTClient client = new RESTClient(config).
659 addHeader('X-TransactionId', aaiRequestId).
660 addHeader('X-FromAppId', 'MSO').
661 addHeader('Content-Type', 'application/xml').
662 addHeader('Accept','application/xml');
663 msoLogger.debug('sending GET to AAI endpoint \'' + endPoint + '\'')
664 APIResponse response = client.httpGet()
665 msoLogger.debug("createVfModule - invoking httpGet() to AAI")
667 responseData = response.getResponseBodyAsString()
668 if (responseData != null) {
669 msoLogger.debug("Received generic VNF data: " + responseData)
673 msoLogger.debug("deleteVfModule - queryAAIVfModule Response: " + responseData)
674 msoLogger.debug("deleteVfModule - queryAAIVfModule ResponseCode: " + response.getStatusCode())
676 execution.setVariable(Prefix + 'queryAAIVfModuleForStatusResponseCode', response.getStatusCode())
677 execution.setVariable(Prefix + 'queryAAIVfModuleForStatusResponse', responseData)
678 msoLogger.debug('Response code:' + response.getStatusCode())
679 msoLogger.debug('Response:' + System.lineSeparator() + responseData)
680 // Retrieve VF Module info and its orchestration status; if not found, do nothing
681 if (response.getStatusCode() == 200) {
682 // Parse the VNF record from A&AI to find base module info
683 msoLogger.debug('Parsing the VNF data to find orchestration status')
684 if (responseData != null) {
685 def vfModuleText = utils.getNodeXml(responseData, "vf-module")
686 //def xmlVfModule= new XmlSlurper().parseText(vfModuleText)
687 def orchestrationStatus = utils.getNodeText(vfModuleText, "orchestration-status")
688 execution.setVariable(Prefix + "orchestrationStatus", orchestrationStatus)
689 msoLogger.debug("Received orchestration status from A&AI: " + orchestrationStatus)
693 } catch (Exception ex) {
695 msoLogger.debug('Exception occurred while executing AAI GET:' + ex.getMessage())
696 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'AAI GET Failed:' + ex.getMessage())
698 msoLogger.trace('Exited ' + method)
699 } catch (BpmnError e) {
701 } catch (Exception e) {
702 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
703 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in queryAAIVfModuleForStatus(): ' + e.getMessage())