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.ws.rs.core.Response
25 import javax.xml.parsers.DocumentBuilder
26 import javax.xml.parsers.DocumentBuilderFactory
28 import org.apache.commons.lang3.*
29 import org.camunda.bpm.engine.delegate.BpmnError
30 import org.camunda.bpm.engine.delegate.DelegateExecution
31 import org.json.JSONArray
32 import org.json.JSONObject
33 import org.onap.so.bpmn.common.scripts.AaiUtil
34 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
35 import org.onap.so.bpmn.common.scripts.ExceptionUtil
36 import org.onap.so.bpmn.common.scripts.MsoUtils
37 import org.onap.so.bpmn.core.WorkflowException
38 import org.onap.so.bpmn.core.domain.Resource
39 import org.onap.so.bpmn.core.domain.ServiceDecomposition
41 import org.onap.so.utils.TargetEntity
42 import org.onap.so.bpmn.core.json.JsonUtils
43 import org.onap.so.client.HttpClient
44 import org.springframework.web.util.UriUtils;
45 import org.w3c.dom.Document
46 import org.w3c.dom.Element
47 import org.w3c.dom.Node
48 import org.w3c.dom.NodeList
49 import org.xml.sax.InputSource
54 * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
57 * @param - msoRequestId
58 * @param - globalSubscriberId - O
59 * @param - subscriptionServiceType - O
60 * @param - serviceInstanceId
61 * @param - serviceInstanceName - O
62 * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
63 * @param - sdncVersion
64 * @param - failNotFound - TODO
65 * @param - serviceInputParams - TODO
67 * @param - delResourceList
68 * @param - serviceRelationShip
71 * @param - WorkflowException
75 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
77 String Prefix="DDEESI_"
78 ExceptionUtil exceptionUtil = new ExceptionUtil()
79 JsonUtils jsonUtil = new JsonUtils()
81 public void preProcessRequest (DelegateExecution execution) {
82 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
83 utils.log("INFO"," ***** preProcessRequest *****", isDebugEnabled)
87 String requestId = execution.getVariable("msoRequestId")
88 execution.setVariable("prefix",Prefix)
91 //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
92 String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
93 if (globalSubscriberId == null)
95 execution.setVariable("globalSubscriberId", "")
98 //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
99 String serviceType = execution.getVariable("serviceType")
100 if (serviceType == null)
102 execution.setVariable("serviceType", "")
105 //Generated in parent for AAI PUT
106 String serviceInstanceId = execution.getVariable("serviceInstanceId")
107 if (isBlank(serviceInstanceId)){
108 msg = "Input serviceInstanceId is null"
109 utils.log("INFO", msg, isDebugEnabled)
110 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
113 String sdncCallbackUrl = execution.getVariable('URN_mso_workflow_sdncadapter_callback')
114 if (isBlank(sdncCallbackUrl)) {
115 msg = "URN_mso_workflow_sdncadapter_callback is null"
116 utils.log("INFO", msg, isDebugEnabled)
117 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
119 execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
120 utils.log("INFO","SDNC Callback URL: " + sdncCallbackUrl, isDebugEnabled)
122 StringBuilder sbParams = new StringBuilder()
123 Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
124 if (paramsMap != null)
126 sbParams.append("<service-input-parameters>")
127 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
129 String paramName = entry.getKey()
130 String paramValue = entry.getValue()
133 <name>${MsoUtils.xmlEscape(paramName)}</name>
134 <value>${MsoUtils.xmlEscape(paramValue)}</value>
137 sbParams.append(paramsXml)
139 sbParams.append("</service-input-parameters>")
141 String siParamsXml = sbParams.toString()
142 if (siParamsXml == null)
144 execution.setVariable("siParamsXml", siParamsXml)
146 } catch (BpmnError e) {
148 } catch (Exception ex){
149 msg = "Exception in preProcessRequest " + ex.getMessage()
150 utils.log("INFO", msg, isDebugEnabled)
151 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
153 utils.log("INFO"," ***** Exit preProcessRequest *****", isDebugEnabled)
156 public void postProcessAAIGET(DelegateExecution execution) {
157 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
158 utils.log("INFO"," ***** postProcessAAIGET ***** ", isDebugEnabled)
162 String serviceInstanceId = execution.getVariable("serviceInstanceId")
163 boolean foundInAAI = execution.getVariable("GENGS_FoundIndicator")
164 String serviceType = ""
167 utils.log("INFO","Found Service-instance in AAI", isDebugEnabled)
169 String siData = execution.getVariable("GENGS_service")
170 utils.log("INFO", "SI Data", isDebugEnabled)
173 msg = "Could not retrive ServiceInstance data from AAI to delete id:" + serviceInstanceId
174 utils.log("INFO", msg, isDebugEnabled)
175 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
179 InputSource source = new InputSource(new StringReader(siData));
180 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
181 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
182 Document serviceXml = docBuilder.parse(source)
183 serviceXml.getDocumentElement().normalize()
184 // get model invariant id
185 // Get Template uuid and version
186 if (utils.nodeExists(siData, "model-invariant-id") && utils.nodeExists(siData, "model-version-id") ) {
187 utils.log("INFO", "SI Data model-invariant-id and model-version-id exist:", isDebugEnabled)
188 def modelInvariantId = serviceXml.getElementsByTagName("model-invariant-id").item(0).getTextContent()
189 def modelVersionId = serviceXml.getElementsByTagName("model-version-id").item(0).getTextContent()
191 // Set Original Template info
192 execution.setVariable("model-invariant-id-original", modelInvariantId)
193 execution.setVariable("model-version-id-original", modelVersionId)
196 utils.log("INFO", "SI Data" + siData, isDebugEnabled)
197 //Confirm there are no related service instances (vnf/network or volume)
198 if (utils.nodeExists(siData, "relationship-list")) {
199 utils.log("INFO", "SI Data relationship-list exists:", isDebugEnabled)
200 JSONArray jArray = new JSONArray()
202 XmlParser xmlParser = new XmlParser()
203 Node root = xmlParser.parseText(siData)
204 def relation_list = utils.getChildNode(root, 'relationship-list')
205 def relationships = utils.getIdenticalChildren(relation_list, 'relationship')
207 for (def relation: relationships) {
208 def jObj = getRelationShipData(relation, isDebugEnabled)
212 execution.setVariable("serviceRelationShip", jArray.toString())
215 // NodeList nodeList = serviceXml.getElementsByTagName("relationship")
216 // JSONArray jArray = new JSONArray()
217 // for (int x = 0; x < nodeList.getLength(); x++) {
218 // Node node = nodeList.item(x)
219 // if (node.getNodeType() == Node.ELEMENT_NODE) {
220 // Element eElement = (Element) node
221 // def e = eElement.getElementsByTagName("related-to").item(0).getTextContent() //for ns
222 // if(e.equals("service-instance")){
223 // def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
224 // utils.log("INFO", "ServiceInstance Related NS :" + relatedObject, isDebugEnabled)
225 // NodeList dataList = node.getChildNodes()
226 // if(null != dataList) {
227 // JSONObject jObj = new JSONObject()
228 // for (int i = 0; i < dataList.getLength(); i++) {
229 // Node dNode = dataList.item(i)
230 // if(dNode.getNodeName() == "relationship-data") {
231 // Element rDataEle = (Element)dNode
232 // def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
233 // def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
234 // if(eKey.equals("service-instance.service-instance-id")){
235 // jObj.put("resourceInstanceId", eValue)
239 // else if(dNode.getNodeName() == "related-to-property"){
240 // Element rDataEle = (Element)dNode
241 // def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
242 // def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
243 // if(eKey.equals("service-instance.service-instance-name")){
244 // jObj.put("resourceType", eValue)
248 // utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
251 // //for overlay/underlay
252 // }else if (e.equals("configuration")){
253 // def relatedObject = eElement.getElementsByTagName("related-link").item(0).getTextContent()
254 // utils.log("INFO", "ServiceInstance Related Configuration :" + relatedObject, isDebugEnabled)
255 // NodeList dataList = node.getChildNodes()
256 // if(null != dataList) {
257 // JSONObject jObj = new JSONObject()
258 // for (int i = 0; i < dataList.getLength(); i++) {
259 // Node dNode = dataList.item(i)
260 // if(dNode.getNodeName() == "relationship-data") {
261 // Element rDataEle = (Element)dNode
262 // def eKey = rDataEle.getElementsByTagName("relationship-key").item(0).getTextContent()
263 // def eValue = rDataEle.getElementsByTagName("relationship-value").item(0).getTextContent()
264 // if(eKey.equals("configuration.configuration-id")){
265 // jObj.put("resourceInstanceId", eValue)
268 // else if(dNode.getNodeName() == "related-to-property"){
269 // Element rDataEle = (Element)dNode
270 // def eKey = rDataEle.getElementsByTagName("property-key").item(0).getTextContent()
271 // def eValue = rDataEle.getElementsByTagName("property-value").item(0).getTextContent()
272 // if(eKey.equals("configuration.configuration-type")){
273 // jObj.put("resourceType", eValue)
277 // utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
281 // }else if (e.equals("sp-partner")){
286 // execution.setVariable("serviceRelationShip", jArray.toString())
290 boolean succInAAI = execution.getVariable("GENGS_SuccessIndicator")
292 utils.log("INFO","Error getting Service-instance from AAI", + serviceInstanceId, isDebugEnabled)
293 WorkflowException workflowException = execution.getVariable("WorkflowException")
294 utils.logAudit("workflowException: " + workflowException)
295 if(workflowException != null){
296 exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
300 msg = "Failure in postProcessAAIGET GENGS_SuccessIndicator:" + succInAAI
301 utils.log("INFO", msg, isDebugEnabled)
302 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
306 utils.log("INFO","Service-instance NOT found in AAI. Silent Success", isDebugEnabled)
308 }catch (BpmnError e) {
310 } catch (Exception ex) {
311 msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
312 utils.log("INFO", msg, isDebugEnabled)
313 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
315 utils.log("INFO"," *** Exit postProcessAAIGET *** ", isDebugEnabled)
318 private JSONObject getRelationShipData(node, isDebugEnabled){
319 JSONObject jObj = new JSONObject()
321 def relation = utils.nodeToString(node)
322 def rt = utils.getNodeText(relation, "related-to")
324 def rl = utils.getNodeText(relation, "related-link")
325 utils.log("INFO", "ServiceInstance Related NS/Configuration :" + rl, isDebugEnabled)
327 def rl_datas = utils.getIdenticalChildren(node, "relationship-data")
328 for(def rl_data : rl_datas) {
329 def eKey = utils.getChildNodeText(rl_data, "relationship-key")
330 def eValue = utils.getChildNodeText(rl_data, "relationship-value")
332 if ((rt == "service-instance" && eKey.equals("service-instance.service-instance-id"))
333 //for overlay/underlay
334 || (rt == "configuration" && eKey.equals("configuration.configuration-id")
336 jObj.put("resourceInstanceId", eValue)
338 // for sp-partner and others
339 else if(eKey.endsWith("-id")){
340 jObj.put("resourceInstanceId", eValue)
341 String resourceName = rt + eValue;
342 jObj.put("resourceType", resourceName)
345 jObj.put("resourceLinkUrl", rl)
348 def rl_props = utils.getIdenticalChildren(node, "related-to-property")
349 for(def rl_prop : rl_props) {
350 def eKey = utils.getChildNodeText(rl_prop, "property-key")
351 def eValue = utils.getChildNodeText(rl_prop, "property-value")
352 if((rt == "service-instance" && eKey.equals("service-instance.service-instance-name"))
353 //for overlay/underlay
354 || (rt == "configuration" && eKey.equals("configuration.configuration-type"))){
355 jObj.put("resourceType", eValue)
359 utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
364 public void getCurrentNS(DelegateExecution execution){
365 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
366 utils.log("INFO", "======== Start getCurrentNS Process ======== ", isDebugEnabled)
368 def currentIndex = execution.getVariable("currentNSIndex")
369 List<String> nsSequence = execution.getVariable("nsSequence")
370 String nsResourceType = nsSequence.get(currentIndex)
372 // GET AAI by Name, not ID, for process convenient
373 execution.setVariable("GENGS_type", "service-instance")
374 execution.setVariable("GENGS_serviceInstanceId", "")
375 execution.setVariable("GENGS_serviceInstanceName", nsResourceType)
377 utils.log("INFO", "======== COMPLETED getCurrentNS Process ======== ", isDebugEnabled)
380 public void prepareDecomposeService(DelegateExecution execution) {
381 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
384 utils.log("DEBUG", " ***** Inside prepareDecomposeService of create generic e2e service ***** ", isDebugEnabled)
385 String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
386 String modelVersionId = execution.getVariable("model-version-id-original")
388 String serviceModelInfo = """{
389 "modelInvariantUuid":"${modelInvariantUuid}",
390 "modelUuid":"${modelVersionId}",
393 execution.setVariable("serviceModelInfo", serviceModelInfo)
395 utils.log("DEBUG", " ***** Completed prepareDecomposeService of create generic e2e service ***** ", isDebugEnabled)
396 } catch (Exception ex) {
397 // try error in method block
398 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
399 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
403 private void generateRelatedResourceInfo(String response, JSONObject jObj){
405 def xml = new XmlSlurper().parseText(response)
406 def rtn = xml.childNodes()
407 while (rtn.hasNext()) {
408 groovy.util.slurpersupport.Node node = rtn.next()
409 def key = node.name()
410 def value = node.text()
415 private JSONObject getRelatedResourceInAAI (DelegateExecution execution, JSONObject jObj)
417 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
418 utils.log("INFO"," ***** Started getRelatedResourceInAAI *****", isDebugEnabled)
420 AaiUtil aaiUriUtil = new AaiUtil()
421 String aai_endpoint = execution.getVariable("URN_aai_endpoint")
422 String urlLink = jObj.get("resourceLinkUrl")
423 String serviceAaiPath = "${aai_endpoint}${urlLink}"
425 URL url = new URL(serviceAaiPath)
426 HttpClient client = new HttpClient(url, "application/xml", TargetEntity.AAI)
429 Response response = client.get()
430 int responseCode = response.getStatus()
431 execution.setVariable(Prefix + "GeRelatedResourceResponseCode", responseCode)
432 utils.log("DEBUG", " Get RelatedResource code is: " + responseCode, isDebugEnabled)
434 String aaiResponse = response.readEntity(String.class)
435 execution.setVariable(Prefix + "GetRelatedResourceResponse", aaiResponse)
438 if(responseCode == 200 || responseCode == 201 || responseCode == 202 )
439 //200 OK 201 CREATED 202 ACCEPTED
441 utils.log("DEBUG", "GET RelatedResource Received a Good Response", isDebugEnabled)
442 execution.setVariable(Prefix + "SuccessIndicator", true)
443 execution.setVariable(Prefix + "FoundIndicator", true)
445 generateRelatedResourceInfo(aaiResponse, jObj)
447 //get model-invariant-uuid and model-uuid
448 String modelInvariantId = ""
449 String modelUuid = ""
450 String modelCustomizationId = ""
451 if(jObj.has("model-invariant-id")) {
452 modelInvariantId = jObj.get("model-invariant-id")
453 modelUuid = jObj.get("model-version-id")
454 modelCustomizationId = jObj.get("model-customization-id")
457 jObj.put("modelInvariantId", modelInvariantId)
458 jObj.put("modelVersionId", modelUuid)
459 jObj.put("modelCustomizationId", modelCustomizationId)
463 utils.log("ERROR", "Get RelatedResource Received a Bad Response Code. Response Code is: " + responseCode, isDebugEnabled)
466 utils.log("INFO", " ***** Exit getRelatedResourceInAAI *****", isDebugEnabled)
471 public void postDecomposeService(DelegateExecution execution) {
472 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
474 utils.log("DEBUG", " ***** Inside processDecomposition() of delete generic e2e service flow ***** ", isDebugEnabled)
476 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
478 // service model info
479 execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
481 List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
482 String serviceRelationShip = execution.getVariable("serviceRelationShip")
483 def jsonSlurper = new JsonSlurper()
484 def jsonOutput = new JsonOutput()
486 List relationShipList = null
487 if (serviceRelationShip != null) {
488 relationShipList = jsonSlurper.parseText(serviceRelationShip)
491 List<Resource> deleteRealResourceList = new ArrayList<Resource>()
493 //Set the real resource instance id to the decomosed resource list
494 //reset the resource instance id , because in the decompose flow ,its a random one.
495 //match the resource-instance-name and the model name
496 if (relationShipList != null) {
497 relationShipList.each {
499 JSONObject obj = getRelatedResourceInAAI(execution, (JSONObject)it)
501 for (Resource resource : deleteResourceList) {
503 String modelName = resource.getModelInfo().getModelName()
505 String modelCustomizationUuid = resource.getModelInfo().getModelCustomizationUuid()
506 if (StringUtils.containsIgnoreCase(obj.get("resourceType"), modelName)) {
507 resource.setResourceId(obj.get("resourceInstanceId"))
508 deleteRealResourceList.add(resource)
510 else if (modelCustomizationUuid.equals(obj.get("modelCustomizationId"))) {
511 resource.setResourceId(obj.get("resourceInstanceId"))
512 resource.setResourceInstanceName(obj.get("resourceType"))
513 deleteRealResourceList.add(resource)
519 // only delete real existing resources
520 execution.setVariable("deleteResourceList", deleteRealResourceList)
522 utils.log("DEBUG", "delete resource list : " + deleteRealResourceList, isDebugEnabled)
523 } catch (Exception ex) {
524 String exceptionMessage = "Bpmn error encountered in create generic e2e service flow. processDecomposition() - " + ex.getMessage()
525 utils.log("DEBUG", exceptionMessage, isDebugEnabled)
526 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
528 utils.log("DEBUG", " ***** exit processDecomposition() of delete generic e2e service flow ***** ", isDebugEnabled)
531 public void preInitResourcesOperStatus(DelegateExecution execution){
532 def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
534 utils.log("INFO", " ======== STARTED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
536 String serviceId = execution.getVariable("serviceInstanceId")
537 String operationId = execution.getVariable("operationId")
538 String operationType = execution.getVariable("operationType")
539 String resourceTemplateUUIDs = ""
540 String result = "processing"
541 String progress = "0"
543 String operationContent = "Prepare service creation"
544 utils.log("INFO", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType, isDebugEnabled)
545 serviceId = UriUtils.encode(serviceId,"UTF-8")
546 execution.setVariable("serviceInstanceId", serviceId)
547 execution.setVariable("operationId", operationId)
548 execution.setVariable("operationType", operationType)
549 List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
551 String serviceRelationShip = execution.getVariable("serviceRelationShip")
552 for(Resource resource : deleteResourceList){
553 resourceTemplateUUIDs = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
557 execution.setVariable("URN_mso_adapters_openecomp_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
560 """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
561 xmlns:ns="http://org.onap.so/requestsdb">
564 <ns:initResourceOperationStatus xmlns:ns="http://org.onap.so/requestsdb">
565 <serviceId>${MsoUtils.xmlEscape(serviceId)}</serviceId>
566 <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
567 <operationType>${MsoUtils.xmlEscape(operationType)}</operationType>
568 <resourceTemplateUUIDs>${MsoUtils.xmlEscape(resourceTemplateUUIDs)}</resourceTemplateUUIDs>
569 </ns:initResourceOperationStatus>
571 </soapenv:Envelope>"""
573 payload = utils.formatXml(payload)
574 execution.setVariable("CVFMI_initResOperStatusRequest", payload)
575 utils.log("INFO", "Outgoing initResourceOperationStatus: \n" + payload, isDebugEnabled)
576 utils.logAudit("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
579 utils.log("ERROR", "Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e, isDebugEnabled)
580 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
582 utils.log("INFO", "======== COMPLETED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
586 * post config request.
588 public void postConfigRequest(execution){