2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Huawei Technologies Co., Ltd. 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=========================================================
20 package org.onap.so.bpmn.infrastructure.scripts
22 import static org.apache.commons.lang3.StringUtils.*;
24 import javax.xml.parsers.DocumentBuilder
25 import javax.xml.parsers.DocumentBuilderFactory
27 import org.apache.commons.lang3.*
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
30 import org.json.JSONArray
31 import org.json.JSONObject
32 import org.onap.so.bpmn.common.scripts.AaiUtil
33 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
34 import org.onap.so.bpmn.common.scripts.ExceptionUtil
35 import org.onap.so.bpmn.common.scripts.MsoUtils
36 import org.onap.so.bpmn.core.WorkflowException
37 import org.onap.so.bpmn.core.domain.Resource
38 import org.onap.so.bpmn.core.domain.ServiceDecomposition
39 import org.onap.so.rest.APIResponse
40 import org.onap.so.bpmn.core.json.JsonUtils
41 import org.springframework.web.util.UriUtils;
42 import org.w3c.dom.Document
43 import org.w3c.dom.Element
44 import org.w3c.dom.Node
45 import org.w3c.dom.NodeList
46 import org.xml.sax.InputSource
51 * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
54 * @param - msoRequestId
55 * @param - globalSubscriberId - O
56 * @param - subscriptionServiceType - O
57 * @param - serviceInstanceId
58 * @param - serviceInstanceName - O
59 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
60 * @param - sdncVersion
61 * @param - failNotFound - TODO
62 * @param - serviceInputParams - TODO
64 * @param - delResourceList
65 * @param - serviceRelationShip
68 * @param - WorkflowException
72 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
74 String Prefix="DDEESI_"
75 ExceptionUtil exceptionUtil = new ExceptionUtil()
76 JsonUtils jsonUtil = new JsonUtils()
78 public void preProcessRequest (DelegateExecution execution) {
79 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
80 utils.log("INFO"," ***** preProcessRequest *****", isDebugEnabled)
84 String requestId = execution.getVariable("msoRequestId")
85 execution.setVariable("prefix",Prefix)
88 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
89 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
90 if (globalSubscriberId == null)
92 execution.setVariable("globalSubscriberId", "")
95 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
96 String serviceType = execution.getVariable("serviceType")
97 if (serviceType == null)
99 execution.setVariable("serviceType", "")
102 //Generated in parent for AAI PUT
103 String serviceInstanceId = execution.getVariable("serviceInstanceId")
104 if (isBlank(serviceInstanceId)){
105 msg = "Input serviceInstanceId is null"
106 utils.log("INFO", msg, isDebugEnabled)
107 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
110 String sdncCallbackUrl = execution.getVariable('URN_mso_workflow_sdncadapter_callback')
111 if (isBlank(sdncCallbackUrl)) {
112 msg = "URN_mso_workflow_sdncadapter_callback is null"
113 utils.log("INFO", msg, isDebugEnabled)
114 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
116 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
117 utils.log("INFO","SDNC Callback URL: " + sdncCallbackUrl, isDebugEnabled)
119 StringBuilder sbParams = new StringBuilder()
120 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
121 if (paramsMap != null)
123 sbParams.append("<service-input-parameters>")
124 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
126 String paramName = entry.getKey()
127 String paramValue = entry.getValue()
130 <name>${MsoUtils.xmlEscape(paramName)}</name>
131 <value>${MsoUtils.xmlEscape(paramValue)}</value>
134 sbParams.append(paramsXml)
136 sbParams.append("</service-input-parameters>")
138 String siParamsXml = sbParams.toString()
139 if (siParamsXml == null)
141 execution.setVariable("siParamsXml", siParamsXml)
143 } catch (BpmnError e) {
145 } catch (Exception ex){
146 msg = "Exception in preProcessRequest " + ex.getMessage()
147 utils.log("INFO", msg, isDebugEnabled)
148 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
150 utils.log("INFO"," ***** Exit preProcessRequest *****", isDebugEnabled)
153 public void postProcessAAIGET(DelegateExecution execution) {
154 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
155 utils.log("INFO"," ***** postProcessAAIGET ***** ", isDebugEnabled)
159 String serviceInstanceId = execution.getVariable("serviceInstanceId")
160 boolean foundInAAI = execution.getVariable("GENGS_FoundIndicator")
161 String serviceType = ""
164 utils.log("INFO","Found Service-instance in AAI", isDebugEnabled)
166 String siData = execution.getVariable("GENGS_service")
167 utils.log("INFO", "SI Data", isDebugEnabled)
170 msg = "Could not retrive ServiceInstance data from AAI to delete id:" + serviceInstanceId
171 utils.log("INFO", msg, isDebugEnabled)
172 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
176 InputSource source = new InputSource(new StringReader(siData));
177 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
178 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
179 Document serviceXml = docBuilder.parse(source)
180 serviceXml.getDocumentElement().normalize()
181 // get model invariant id
182 // Get Template uuid and version
183 if (utils.nodeExists(siData, "model-invariant-id") && utils.nodeExists(siData, "model-version-id") ) {
184 utils.log("INFO", "SI Data model-invariant-id and model-version-id exist:", isDebugEnabled)
185 def modelInvariantId = serviceXml.getElementsByTagName("model-invariant-id").item(0).getTextContent()
186 def modelVersionId = serviceXml.getElementsByTagName("model-version-id").item(0).getTextContent()
188 // Set Original Template info
189 execution.setVariable("model-invariant-id-original", modelInvariantId)
190 execution.setVariable("model-version-id-original", modelVersionId)
193 utils.log("INFO", "SI Data" + siData, isDebugEnabled)
194 //Confirm there are no related service instances (vnf/network or volume)
195 if (utils.nodeExists(siData, "relationship-list")) {
196 utils.log("INFO", "SI Data relationship-list exists:", isDebugEnabled)
197 JSONArray jArray = new JSONArray()
199 XmlParser xmlParser = new XmlParser()
200 Node root = xmlParser.parseText(siData)
201 def relation_list = utils.getChildNode(root, 'relationship-list')
202 def relationships = utils.getIdenticalChildren(relation_list, 'relationship')
204 for (def relation: relationships) {
205 def jObj = getRelationShipData(relation, isDebugEnabled)
209 execution.setVariable("serviceRelationShip", jArray.toString())
212 // NodeList nodeList = serviceXml.getElementsByTagName("relationship")
213 // JSONArray jArray = new JSONArray()
214 // for (int x = 0; x < nodeList.getLength(); x++) {
215 // Node node = nodeList.item(x)
216 // if (node.getNodeType() == Node.ELEMENT_NODE) {
217 // Element eElement = (Element) node
218 // def e = eElement.getElementsByTagName("related-to").item(0).getTextContent() //for ns
219 // if(e.equals("service-instance")){
220 // def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
221 // utils.log("INFO", "ServiceInstance Related NS :" + relatedObject, isDebugEnabled)
222 // NodeList dataList = node.getChildNodes()
223 // if(null != dataList) {
224 // JSONObject jObj = new JSONObject()
225 // for (int i = 0; i < dataList.getLength(); i++) {
226 // Node dNode = dataList.item(i)
227 // if(dNode.getNodeName() == "relationship-data") {
228 // Element rDataEle = (Element)dNode
229 // def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
230 // def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
231 // if(eKey.equals("service-instance.service-instance-id")){
232 // jObj.put("resourceInstanceId", eValue)
236 // else if(dNode.getNodeName() == "related-to-property"){
237 // Element rDataEle = (Element)dNode
238 // def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
239 // def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
240 // if(eKey.equals("service-instance.service-instance-name")){
241 // jObj.put("resourceType", eValue)
245 // utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
248 // //for overlay/underlay
249 // }else if (e.equals("configuration")){
250 // def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
251 // utils.log("INFO", "ServiceInstance Related Configuration :" + relatedObject, isDebugEnabled)
252 // NodeList dataList = node.getChildNodes()
253 // if(null != dataList) {
254 // JSONObject jObj = new JSONObject()
255 // for (int i = 0; i < dataList.getLength(); i++) {
256 // Node dNode = dataList.item(i)
257 // if(dNode.getNodeName() == "relationship-data") {
258 // Element rDataEle = (Element)dNode
259 // def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
260 // def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
261 // if(eKey.equals("configuration.configuration-id")){
262 // jObj.put("resourceInstanceId", eValue)
265 // else if(dNode.getNodeName() == "related-to-property"){
266 // Element rDataEle = (Element)dNode
267 // def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
268 // def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
269 // if(eKey.equals("configuration.configuration-type")){
270 // jObj.put("resourceType", eValue)
274 // utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
278 // }else if (e.equals("sp-partner")){
283 // execution.setVariable("serviceRelationShip", jArray.toString())
287 boolean succInAAI = execution.getVariable("GENGS_SuccessIndicator")
289 utils.log("INFO","Error getting Service-instance from AAI", + serviceInstanceId, isDebugEnabled)
290 WorkflowException workflowException = execution.getVariable("WorkflowException")
291 utils.logAudit("workflowException: " + workflowException)
292 if(workflowException != null){
293 exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
297 msg = "Failure in postProcessAAIGET GENGS_SuccessIndicator:" + succInAAI
298 utils.log("INFO", msg, isDebugEnabled)
299 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
303 utils.log("INFO","Service-instance NOT found in AAI. Silent Success", isDebugEnabled)
305 }catch (BpmnError e) {
307 } catch (Exception ex) {
308 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
309 utils.log("INFO", msg, isDebugEnabled)
310 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
312 utils.log("INFO"," *** Exit postProcessAAIGET *** ", isDebugEnabled)
315 private JSONObject getRelationShipData(node, isDebugEnabled){
316 JSONObject jObj = new JSONObject()
318 def relation = utils.nodeToString(node)
319 def rt = utils.getNodeText(relation, "related-to")
321 def rl = utils.getNodeText(relation, "related-link")
322 utils.log("INFO", "ServiceInstance Related NS/Configuration :" + rl, isDebugEnabled)
324 def rl_datas = utils.getIdenticalChildren(node, "relationship-data")
325 for(def rl_data : rl_datas) {
326 def eKey = utils.getChildNodeText(rl_data, "relationship-key")
327 def eValue = utils.getChildNodeText(rl_data, "relationship-value")
329 if ((rt == "service-instance" && eKey.equals("service-instance.service-instance-id"))
330 //for overlay/underlay
331 || (rt == "configuration" && eKey.equals("configuration.configuration-id")
333 jObj.put("resourceInstanceId", eValue)
335 // for sp-partner and others
336 else if(eKey.endsWith("-id")){
337 jObj.put("resourceInstanceId", eValue)
338 String resourceName = rt + eValue;
339 jObj.put("resourceType", resourceName)
342 jObj.put("resourceLinkUrl", rl)
345 def rl_props = utils.getIdenticalChildren(node, "related-to-property")
346 for(def rl_prop : rl_props) {
347 def eKey = utils.getChildNodeText(rl_prop, "property-key")
348 def eValue = utils.getChildNodeText(rl_prop, "property-value")
349 if((rt == "service-instance" && eKey.equals("service-instance.service-instance-name"))
350 //for overlay/underlay
351 || (rt == "configuration" && eKey.equals("configuration.configuration-type"))){
352 jObj.put("resourceType", eValue)
356 utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
361 public void getCurrentNS(DelegateExecution execution){
362 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
363 utils.log("INFO", "======== Start getCurrentNS Process ======== ", isDebugEnabled)
365 def currentIndex = execution.getVariable("currentNSIndex")
366 List<String> nsSequence = execution.getVariable("nsSequence")
367 String nsResourceType = nsSequence.get(currentIndex)
369 // GET AAI by Name, not ID, for process convenient
370 execution.setVariable("GENGS_type", "service-instance")
371 execution.setVariable("GENGS_serviceInstanceId", "")
372 execution.setVariable("GENGS_serviceInstanceName", nsResourceType)
374 utils.log("INFO", "======== COMPLETED getCurrentNS Process ======== ", isDebugEnabled)
377 public void prepareDecomposeService(DelegateExecution execution) {
378 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
381 utils.log("DEBUG", " ***** Inside prepareDecomposeService of create generic e2e service ***** ", isDebugEnabled)
382 String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
383 String modelVersionId = execution.getVariable("model-version-id-original")
385 String serviceModelInfo = """{
386 "modelInvariantUuid":"${modelInvariantUuid}",
387 "modelUuid":"${modelVersionId}",
390 execution.setVariable("serviceModelInfo", serviceModelInfo)
392 utils.log("DEBUG", " ***** Completed prepareDecomposeService of create generic e2e service ***** ", isDebugEnabled)
393 } catch (Exception ex) {
394 // try error in method block
395 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
396 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
400 private void generateRelatedResourceInfo(String response, JSONObject jObj){
402 def xml = new XmlSlurper().parseText(response)
403 def rtn = xml.childNodes()
404 while (rtn.hasNext()) {
405 groovy.util.slurpersupport.Node node = rtn.next()
406 def key = node.name()
407 def value = node.text()
412 private JSONObject getRelatedResourceInAAI (DelegateExecution execution, JSONObject jObj)
414 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
415 utils.log("INFO"," ***** Started getRelatedResourceInAAI *****", isDebugEnabled)
417 AaiUtil aaiUriUtil = new AaiUtil()
418 String aai_endpoint = execution.getVariable("URN_aai_endpoint")
419 String urlLink = jObj.get("resourceLinkUrl")
420 String serviceAaiPath = "${aai_endpoint}${urlLink}"
421 APIResponse response = aaiUriUtil.executeAAIGetCall(execution, serviceAaiPath)
422 int responseCode = response.getStatusCode()
423 execution.setVariable(Prefix + "GeRelatedResourceResponseCode", responseCode)
424 utils.log("DEBUG", " Get RelatedResource code is: " + responseCode, isDebugEnabled)
426 String aaiResponse = response.getResponseBodyAsString()
427 aaiResponse = StringEscapeUtils.unescapeXml(aaiResponse)
428 aaiResponse = aaiResponse.replaceAll("&", "&")
429 execution.setVariable(Prefix + "GetRelatedResourceResponse", aaiResponse)
432 if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
433 //200 OK 201 CREATED 202 ACCEPTED
435 utils.log("DEBUG", "GET RelatedResource Received a Good Response", isDebugEnabled)
436 execution.setVariable(Prefix + "SuccessIndicator", true)
437 execution.setVariable(Prefix + "FoundIndicator", true)
439 generateRelatedResourceInfo(aaiResponse, jObj)
441 //get model-invariant-uuid and model-uuid
442 String modelInvariantId = ""
443 String modelUuid = ""
444 String modelCustomizationId = ""
445 if(jObj.has("model-invariant-id")) {
446 modelInvariantId = jObj.get("model-invariant-id")
447 modelUuid = jObj.get("model-version-id")
448 modelCustomizationId = jObj.get("model-customization-id")
451 jObj.put("modelInvariantId", modelInvariantId)
452 jObj.put("modelVersionId", modelUuid)
453 jObj.put("modelCustomizationId", modelCustomizationId)
457 utils.log("ERROR", "Get RelatedResource Received a Bad Response Code. Response Code is: " + responseCode, isDebugEnabled)
460 utils.log("INFO", " ***** Exit getRelatedResourceInAAI *****", isDebugEnabled)
465 public void postDecomposeService(DelegateExecution execution) {
466 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
468 utils.log("DEBUG", " ***** Inside processDecomposition() of delete generic e2e service flow ***** ", isDebugEnabled)
470 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
472 // service model info
473 execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
475 List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
476 String serviceRelationShip = execution.getVariable("serviceRelationShip")
477 def jsonSlurper = new JsonSlurper()
478 def jsonOutput = new JsonOutput()
480 List relationShipList = null
481 if (serviceRelationShip != null) {
482 relationShipList = jsonSlurper.parseText(serviceRelationShip)
485 List<Resource> deleteRealResourceList = new ArrayList<Resource>()
487 //Set the real resource instance id to the decomosed resource list
488 //reset the resource instance id , because in the decompose flow ,its a random one.
489 //match the resource-instance-name and the model name
490 if (relationShipList != null) {
491 relationShipList.each {
493 JSONObject obj = getRelatedResourceInAAI(execution, (JSONObject)it)
495 for (Resource resource : deleteResourceList) {
497 String modelName = resource.getModelInfo().getModelName()
499 String modelCustomizationUuid = resource.getModelInfo().getModelCustomizationUuid()
500 if (StringUtils.containsIgnoreCase(obj.get("resourceType"), modelName)) {
501 resource.setResourceId(obj.get("resourceInstanceId"))
502 deleteRealResourceList.add(resource)
504 else if (modelCustomizationUuid.equals(obj.get("modelCustomizationId"))) {
505 resource.setResourceId(obj.get("resourceInstanceId"))
506 resource.setResourceInstanceName(obj.get("resourceType"))
507 deleteRealResourceList.add(resource)
513 // only delete real existing resources
514 execution.setVariable("deleteResourceList", deleteRealResourceList)
516 utils.log("DEBUG", "delete resource list : " + deleteRealResourceList, isDebugEnabled)
517 } catch (Exception ex) {
518 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. processDecomposition() - " + ex.getMessage()
519 utils.log("DEBUG", exceptionMessage, isDebugEnabled)
520 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
522 utils.log("DEBUG", " ***** exit processDecomposition() of delete generic e2e service flow ***** ", isDebugEnabled)
525 public void preInitResourcesOperStatus(DelegateExecution execution){
526 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
528 utils.log("INFO", " ======== STARTED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
530 String serviceId = execution.getVariable("serviceInstanceId")
531 String operationId = execution.getVariable("operationId")
532 String operationType = execution.getVariable("operationType")
533 String resourceTemplateUUIDs = ""
534 String result = "processing"
535 String progress = "0"
537 String operationContent = "Prepare service creation"
538 utils.log("INFO", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType, isDebugEnabled)
539 serviceId = UriUtils.encode(serviceId,"UTF-8")
540 execution.setVariable("serviceInstanceId", serviceId)
541 execution.setVariable("operationId", operationId)
542 execution.setVariable("operationType", operationType)
543 List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
545 String serviceRelationShip = execution.getVariable("serviceRelationShip")
546 for(Resource resource : deleteResourceList){
547 resourceTemplateUUIDs = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
551 execution.setVariable("URN_mso_adapters_openecomp_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
554 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
555 xmlns:ns="http://org.onap.so/requestsdb">
558 <ns:initResourceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
559 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
560 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
561 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
562 <resourceTemplateUUIDs>${MsoUtils.xmlEscape(resourceTemplateUUIDs)}</resourceTemplateUUIDs>
563 </ns:initResourceOperationStatus>
565 </soapenv:Envelope>"""
567 payload = utils.formatXml(payload)
568 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
569 utils.log("INFO", "Outgoing initResourceOperationStatus: \n" + payload, isDebugEnabled)
570 utils.logAudit("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
573 utils.log("ERROR", "Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e, isDebugEnabled)
574 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
576 utils.log("INFO", "======== COMPLETED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
580 * post config request.
582 public void postConfigRequest(execution){