Merge "Reorder modifiers"
[so.git] / bpmn / MSOInfrastructureBPMN / src / main / groovy / org / openecomp / mso / bpmn / infrastructure / scripts / DoDeleteE2EServiceInstance.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.mso.bpmn.infrastructure.scripts
21
22 import org.apache.http.HttpResponse
23 import org.json.JSONArray
24 import org.openecomp.mso.bpmn.common.recipe.BpmnRestClient
25 import org.openecomp.mso.bpmn.common.recipe.ResourceInput
26 import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition;
27
28 import static org.apache.commons.lang3.StringUtils.*;
29 import groovy.xml.XmlUtil
30 import groovy.json.*
31
32 import org.openecomp.mso.bpmn.core.domain.ModelInfo
33 import org.openecomp.mso.bpmn.core.domain.Resource
34 import org.openecomp.mso.bpmn.core.domain.ServiceInstance
35 import org.openecomp.mso.bpmn.core.json.JsonUtils
36 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor
37 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
38 import org.openecomp.mso.bpmn.common.scripts.SDNCAdapterUtils
39 import org.openecomp.mso.bpmn.core.WorkflowException
40 import org.openecomp.mso.rest.APIResponse;
41 import org.openecomp.mso.rest.RESTClient
42 import org.openecomp.mso.rest.RESTConfig
43
44 import java.util.List;
45 import java.util.UUID;
46 import javax.xml.parsers.DocumentBuilder
47 import javax.xml.parsers.DocumentBuilderFactory
48
49 import org.camunda.bpm.engine.delegate.BpmnError
50 import org.camunda.bpm.engine.delegate.DelegateExecution
51 import org.camunda.bpm.engine.runtime.Execution
52 import org.json.JSONObject;
53 import org.apache.commons.lang3.*
54 import org.apache.commons.codec.binary.Base64;
55 import org.springframework.web.util.UriUtils;
56 import org.w3c.dom.Document
57 import org.w3c.dom.Element
58 import org.w3c.dom.Node
59 import org.w3c.dom.NodeList
60 import org.xml.sax.InputSource
61
62 import com.fasterxml.jackson.jaxrs.json.annotation.JSONP.Def;
63
64 /**
65  * This groovy class supports the <class>DoDeleteE2EServiceInstance.bpmn</class> process.
66  * 
67  * Inputs:
68  * @param - msoRequestId
69  * @param - globalSubscriberId - O
70  * @param - subscriptionServiceType - O
71  * @param - serviceInstanceId
72  * @param - serviceInstanceName - O
73  * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
74  * @param - sdncVersion 
75  * @param - failNotFound - TODO
76  * @param - serviceInputParams - TODO 
77  *
78  * @param - delResourceList
79  * @param - serviceRelationShip
80  *
81  * Outputs:
82  * @param - WorkflowException
83  * 
84  * Rollback - Deferred
85  */
86 public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
87
88         String Prefix="DDEESI_"
89     ExceptionUtil exceptionUtil = new ExceptionUtil()
90     JsonUtils jsonUtil = new JsonUtils()
91
92     public void preProcessRequest (DelegateExecution execution) {
93         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
94         utils.log("INFO"," ***** preProcessRequest *****",  isDebugEnabled)
95         String msg = ""
96
97         try {
98             String requestId = execution.getVariable("msoRequestId")
99             execution.setVariable("prefix",Prefix)
100
101             //Inputs
102             //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
103             String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
104             if (globalSubscriberId == null)
105             {
106                 execution.setVariable("globalSubscriberId", "")
107             }
108
109             //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
110             String serviceType = execution.getVariable("serviceType")
111             if (serviceType == null)
112             {
113                 execution.setVariable("serviceType", "")
114             }
115
116             //Generated in parent for AAI PUT
117             String serviceInstanceId = execution.getVariable("serviceInstanceId")
118             if (isBlank(serviceInstanceId)){
119                 msg = "Input serviceInstanceId is null"
120                 utils.log("INFO", msg, isDebugEnabled)
121                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
122             }
123
124             String sdncCallbackUrl = execution.getVariable('URN_mso_workflow_sdncadapter_callback')
125             if (isBlank(sdncCallbackUrl)) {
126                 msg = "URN_mso_workflow_sdncadapter_callback is null"
127                 utils.log("INFO", msg, isDebugEnabled)
128                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
129             }
130             execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
131             utils.log("INFO","SDNC Callback URL: " + sdncCallbackUrl, isDebugEnabled)
132
133             StringBuilder sbParams = new StringBuilder()
134             Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
135             if (paramsMap != null)
136             {
137                 sbParams.append("<service-input-parameters>")
138                 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
139                     String paramsXml
140                     String paramName = entry.getKey()
141                     String paramValue = entry.getValue()
142                     paramsXml =
143                             """ <param>
144                                                         <name>${paramName}</name>
145                                                         <value>${paramValue}</value>
146                                                         </param>
147                                                         """
148                     sbParams.append(paramsXml)
149                 }
150                 sbParams.append("</service-input-parameters>")
151             }
152             String siParamsXml = sbParams.toString()
153             if (siParamsXml == null)
154                 siParamsXml = ""
155             execution.setVariable("siParamsXml", siParamsXml)
156
157         } catch (BpmnError e) {
158             throw e;
159         } catch (Exception ex){
160             msg = "Exception in preProcessRequest " + ex.getMessage()
161             utils.log("INFO", msg, isDebugEnabled)
162             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
163         }
164         utils.log("INFO"," ***** Exit preProcessRequest *****",  isDebugEnabled)
165     }
166
167     public void postProcessAAIGET(DelegateExecution execution) {
168         def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
169         utils.log("INFO"," ***** postProcessAAIGET ***** ", isDebugEnabled)
170         String msg = ""
171
172         try {
173             String serviceInstanceId = execution.getVariable("serviceInstanceId")
174             boolean foundInAAI = execution.getVariable("GENGS_FoundIndicator")
175             String serviceType = ""
176
177             if(foundInAAI){
178                 utils.log("INFO","Found Service-instance in AAI", isDebugEnabled)
179
180                 String siData = execution.getVariable("GENGS_service")
181                 utils.log("INFO", "SI Data", isDebugEnabled)
182                 if (isBlank(siData))
183                 {
184                     msg = "Could not retrive ServiceInstance data from AAI to delete id:" + serviceInstanceId
185                     utils.log("INFO", msg, isDebugEnabled)
186                     exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
187                 }
188                 else
189                 {
190                     InputSource source = new InputSource(new StringReader(siData));
191                     DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
192                     DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
193                     Document serviceXml = docBuilder.parse(source)
194                     serviceXml.getDocumentElement().normalize()
195                     // get model invariant id
196                     // Get Template uuid and version
197                     if (utils.nodeExists(siData, "model-invariant-id") && utils.nodeExists(siData, "model-version-id") ) {
198                         utils.log("INFO", "SI Data model-invariant-id and model-version-id exist:", isDebugEnabled)
199                         def modelInvariantId  = serviceXml.getElementsByTagName("model-invariant-id").item(0).getTextContent()
200                         def modelVersionId  = serviceXml.getElementsByTagName("model-version-id").item(0).getTextContent()
201
202                         // Set Original Template info
203                         execution.setVariable("model-invariant-id-original", modelInvariantId)
204                         execution.setVariable("model-version-id-original", modelVersionId)
205                     }
206
207                     utils.log("INFO", "SI Data" + siData, isDebugEnabled)
208                     //Confirm there are no related service instances (vnf/network or volume)
209                     if (utils.nodeExists(siData, "relationship-list")) {
210                         utils.log("INFO", "SI Data relationship-list exists:", isDebugEnabled)
211                         //test(siData)
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)
233                                                 }
234
235                                             }
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)
242                                                 }
243                                             }
244                                         }
245                                         utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
246                                         jArray.put(jObj)
247                                     }
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)
263                                                 }
264                                             }
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)
271                                                 }
272                                             }
273                                         }
274                                         utils.log("INFO", "Relationship related to Resource:" + jObj.toString(), isDebugEnabled)
275                                         jArray.put(jObj)
276                                     }
277                                 }
278                             }
279                         }
280                         execution.setVariable("serviceRelationShip", jArray.toString())
281                     }
282                 }
283             }else{
284                 boolean succInAAI = execution.getVariable("GENGS_SuccessIndicator")
285                 if(!succInAAI){
286                     utils.log("INFO","Error getting Service-instance from AAI", + serviceInstanceId, isDebugEnabled)
287                     WorkflowException workflowException = execution.getVariable("WorkflowException")
288                     utils.logAudit("workflowException: " + workflowException)
289                     if(workflowException != null){
290                         exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
291                     }
292                     else
293                     {
294                         msg = "Failure in postProcessAAIGET GENGS_SuccessIndicator:" + succInAAI
295                         utils.log("INFO", msg, isDebugEnabled)
296                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
297                     }
298                 }
299
300                 utils.log("INFO","Service-instance NOT found in AAI. Silent Success", isDebugEnabled)
301             }
302         }catch (BpmnError e) {
303             throw e;
304         } catch (Exception ex) {
305             msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIGET. " + ex.getMessage()
306             utils.log("INFO", msg, isDebugEnabled)
307             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
308         }
309         utils.log("INFO"," *** Exit postProcessAAIGET *** ", isDebugEnabled)
310     }
311
312    public void getCurrentNS(DelegateExecution execution){
313        def isDebugEnabled=execution.getVariable("isDebugLogEnabled")   
314        utils.log("INFO", "======== Start getCurrentNS Process ======== ", isDebugEnabled)    
315        
316        def currentIndex = execution.getVariable("currentNSIndex")
317        List<String> nsSequence = execution.getVariable("nsSequence") 
318        String nsResourceType =  nsSequence.get(currentIndex)
319        
320        // GET AAI by Name, not ID, for process convenient
321        execution.setVariable("GENGS_type", "service-instance")
322        execution.setVariable("GENGS_serviceInstanceId", "") 
323        execution.setVariable("GENGS_serviceInstanceName", nsResourceType)       
324
325        utils.log("INFO", "======== COMPLETED getCurrentNS Process ======== ", isDebugEnabled)  
326    }
327
328     public void prepareDecomposeService(DelegateExecution execution) {
329         def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
330
331         try {
332             utils.log("DEBUG", " ***** Inside prepareDecomposeService of create generic e2e service ***** ", isDebugEnabled)
333             String modelInvariantUuid = execution.getVariable("model-invariant-id-original")
334             String modelVersionId = execution.getVariable("model-version-id-original")
335
336             String serviceModelInfo = """{
337             "modelInvariantUuid":"${modelInvariantUuid}",
338             "modelUuid":"${modelVersionId}",
339             "modelVersion":""
340              }"""
341             execution.setVariable("serviceModelInfo", serviceModelInfo)
342
343             utils.log("DEBUG", " ***** Completed prepareDecomposeService of  create generic e2e service ***** ", isDebugEnabled)
344         } catch (Exception ex) {
345             // try error in method block
346             String exceptionMessage = "Bpmn error encountered in  create generic e2e service flow. Unexpected Error from method prepareDecomposeService() - " + ex.getMessage()
347             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
348         }
349     }
350
351     public void postDecomposeService(DelegateExecution execution) {
352         def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
353
354         utils.log("DEBUG", " ***** Inside processDecomposition() of  delete generic e2e service flow ***** ", isDebugEnabled)
355         try {
356             ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
357
358             // service model info
359             execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
360
361             List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
362             String serviceRelationShip = execution.getVariable("serviceRelationShip")
363             def jsonSlurper = new JsonSlurper()
364             def jsonOutput = new JsonOutput()
365
366             List relationShipList = null
367             if (serviceRelationShip != null) {
368                 relationShipList = jsonSlurper.parseText(serviceRelationShip)
369             }
370
371             //Set the real resource instance id to the decomosed resource list
372             for (Resource resource: deleteResourceList) {
373                 //reset the resource instance id , because in the decompose flow ,its a random one.
374                 resource.setResourceId("");
375                 //match the resource-instance-name and the model name
376                 if (relationShipList != null) {
377                     relationShipList.each {
378                         if (StringUtils.containsIgnoreCase(it.resourceType, resource.getModelInfo().getModelName())) {
379                             resource.setResourceId(it.resourceInstanceId);
380                         }
381                     }
382                 }
383             }
384             execution.setVariable("deleteResourceList", deleteResourceList)
385             utils.log("DEBUG", "delete resource list : " + deleteResourceList, isDebugEnabled)
386         } catch (Exception ex) {
387             String exceptionMessage = "Bpmn error encountered in  create generic e2e service flow. processDecomposition() - " + ex.getMessage()
388             utils.log("DEBUG", exceptionMessage, isDebugEnabled)
389             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
390         }
391         utils.log("DEBUG", " ***** exit processDecomposition() of  delete generic e2e service flow ***** ", isDebugEnabled)
392     }
393
394     public void preInitResourcesOperStatus(DelegateExecution execution){
395         def isDebugEnabled = execution.getVariable("isDebugLogEnabled")
396
397         utils.log("INFO", " ======== STARTED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
398         try{
399             String serviceId = execution.getVariable("serviceInstanceId")
400             String operationId = execution.getVariable("operationId")
401             String operationType = execution.getVariable("operationType")
402             String resourceTemplateUUIDs = ""
403             String result = "processing"
404             String progress = "0"
405             String reason = ""
406             String operationContent = "Prepare service creation"
407             utils.log("INFO", "Generated new operation for Service Instance serviceId:" + serviceId + " operationId:" + operationId + " operationType:" + operationType, isDebugEnabled)
408             serviceId = UriUtils.encode(serviceId,"UTF-8")
409             execution.setVariable("serviceInstanceId", serviceId)
410             execution.setVariable("operationId", operationId)
411             execution.setVariable("operationType", operationType)
412             List<Resource> deleteResourceList = execution.getVariable("deleteResourceList")
413
414             String serviceRelationShip = execution.getVariable("serviceRelationShip")                    
415             for(Resource resource : deleteResourceList){
416                     resourceTemplateUUIDs  = resourceTemplateUUIDs + resource.getModelInfo().getModelCustomizationUuid() + ":"
417             }   
418             
419             
420             execution.setVariable("URN_mso_adapters_openecomp_db_endpoint","http://mso.mso.testlab.openecomp.org:8080/dbadapters/RequestsDbAdapter")
421
422             String payload =
423                     """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
424                         xmlns:ns="http://org.openecomp.mso/requestsdb">
425                         <soapenv:Header/>
426                         <soapenv:Body>
427                             <ns:initResourceOperationStatus xmlns:ns="http://org.openecomp.mso/requestsdb">
428                             <serviceId>${serviceId}</serviceId>
429                             <operationId>${operationId}</operationId>
430                             <operationType>${operationType}</operationType>
431                             <resourceTemplateUUIDs>${resourceTemplateUUIDs}</resourceTemplateUUIDs>
432                         </ns:initResourceOperationStatus>
433                     </soapenv:Body>
434                 </soapenv:Envelope>"""
435
436             payload = utils.formatXml(payload)
437             execution.setVariable("CVFMI_initResOperStatusRequest", payload)
438             utils.log("INFO", "Outgoing initResourceOperationStatus: \n" + payload, isDebugEnabled)
439             utils.logAudit("CreateVfModuleInfra Outgoing initResourceOperationStatus Request: " + payload)
440
441         }catch(Exception e){
442             utils.log("ERROR", "Exception Occured Processing preInitResourcesOperStatus. Exception is:\n" + e, isDebugEnabled)
443             execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during preInitResourcesOperStatus Method:\n" + e.getMessage())
444         }
445         utils.log("INFO", "======== COMPLETED preInitResourcesOperStatus Process ======== ", isDebugEnabled)
446     }
447
448     public void postProcessAAIDEL(DelegateExecution execution) {
449         def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
450         utils.log("INFO"," ***** postProcessAAIDEL ***** ", isDebugEnabled)
451         String msg = ""
452         try {
453             String serviceInstanceId = execution.getVariable("serviceInstanceId")
454             boolean succInAAI = execution.getVariable("GENDS_SuccessIndicator")
455             if(!succInAAI){
456                 msg = "Error deleting Service-instance in AAI" + serviceInstanceId
457                 utils.log("INFO", msg, isDebugEnabled)
458                 WorkflowException workflowException = execution.getVariable("WorkflowException")
459                 utils.logAudit("workflowException: " + workflowException)
460                 if(workflowException != null){
461                     exceptionUtil.buildAndThrowWorkflowException(execution, workflowException.getErrorCode(), workflowException.getErrorMessage())
462                 }
463                 else
464                 {
465                     exceptionUtil.buildAndThrowWorkflowException(execution, 2500, msg)
466                 }
467             }
468         } catch (BpmnError e) {
469             throw e;
470         } catch (Exception ex) {
471             msg = "Exception in DoDeleteE2EServiceInstance.postProcessAAIDEL. " + ex.getMessage()
472             utils.log("INFO", msg, isDebugEnabled)
473             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
474         }
475         utils.log("INFO"," *** Exit postProcessAAIDEL *** ", isDebugEnabled)
476     }
477
478      /**
479       * post config request.
480       */
481      public void postConfigRequest(execution){
482          //to do
483      } 
484    
485 }
486