Fix DeleteE2EServiceInstance flow
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeleteResourcesV1.groovy
1
2 /*-
3  * ============LICENSE_START=======================================================
4  * ONAP - SO
5  * ================================================================================
6  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
7  * ================================================================================
8  * Modifications Copyright (c) 2019 Samsung
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23 package org.onap.so.bpmn.infrastructure.scripts
24
25 import org.onap.so.bpmn.common.scripts.CatalogDbUtilsFactory
26
27 import static org.apache.commons.lang3.StringUtils.isBlank
28
29 import org.apache.commons.lang3.StringUtils
30 import org.apache.http.HttpResponse
31 import org.camunda.bpm.engine.delegate.BpmnError
32 import org.camunda.bpm.engine.delegate.DelegateExecution
33 import org.json.JSONObject
34 import org.onap.so.bpmn.common.recipe.BpmnRestClient
35 import org.onap.so.bpmn.common.recipe.ResourceInput
36 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
37 import org.onap.so.bpmn.common.scripts.CatalogDbUtils
38 import org.onap.so.bpmn.common.scripts.ExceptionUtil
39 import org.onap.so.bpmn.common.scripts.MsoUtils
40 import org.onap.so.bpmn.core.domain.AllottedResource
41 import org.onap.so.bpmn.core.domain.NetworkResource
42 import org.onap.so.bpmn.core.domain.Resource
43 import org.onap.so.bpmn.core.domain.ServiceDecomposition
44 import org.onap.so.bpmn.core.domain.VnfResource
45 import org.onap.so.bpmn.core.json.JsonUtils
46 import org.onap.so.bpmn.core.UrnPropertiesReader
47 import org.onap.so.bpmn.infrastructure.properties.BPMNProperties
48 import org.slf4j.Logger
49 import org.slf4j.LoggerFactory
50
51 /**
52  * input for script :
53  * msoRequestId
54  * isDebugLogEnabled
55  * globalSubscriberId
56  * serviceType
57  * serviceInstanceId
58  * URN_mso_workflow_sdncadapter_callback
59  * serviceInputParams
60  * deleteResourceList
61  * resourceInstanceIDs
62  *
63  * output from script:
64  *
65  */
66
67 public class DoDeleteResourcesV1 extends AbstractServiceTaskProcessor {
68     private static final Logger logger = LoggerFactory.getLogger( DoDeleteResourcesV1.class);
69
70     String Prefix="DDR_"
71     ExceptionUtil exceptionUtil = new ExceptionUtil()
72     JsonUtils jsonUtil = new JsonUtils()
73     CatalogDbUtils catalogDbUtils = new CatalogDbUtilsFactory().create()
74
75     public void preProcessRequest (DelegateExecution execution) {
76         logger.debug(" ***** preProcessRequest *****")
77         String msg = ""
78
79         try {
80             String requestId = execution.getVariable("msoRequestId")
81             execution.setVariable("prefix",Prefix)
82
83             //Inputs
84             //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
85             String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
86             if (globalSubscriberId == null) {
87                 execution.setVariable("globalSubscriberId", "")
88             }
89
90             //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
91             String serviceType = execution.getVariable("serviceType")
92             if (serviceType == null)
93             {
94                 execution.setVariable("serviceType", "")
95             }
96
97             //Generated in parent for AAI PUT
98             String serviceInstanceId = execution.getVariable("serviceInstanceId")
99             if (isBlank(serviceInstanceId)){
100                 msg = "Input serviceInstanceId is null"
101                 logger.error(msg)
102                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
103             }
104
105             String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback', execution)
106             if (isBlank(sdncCallbackUrl)) {
107                 msg = "URN_mso_workflow_sdncadapter_callback is null"
108                 logger.error(msg)
109                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
110             }
111             execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
112             logger.debug("SDNC Callback URL: " + sdncCallbackUrl)
113
114             StringBuilder sbParams = new StringBuilder()
115             Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
116             if (paramsMap != null)
117             {
118                 sbParams.append("<service-input-parameters>")
119                 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
120                     String paramsXml
121                     String paramName = entry.getKey()
122                     String paramValue = entry.getValue()
123                     paramsXml =
124                             """ <param>
125                                                         <name>${MsoUtils.xmlEscape(paramName)}</name>
126                                                         <value>${MsoUtils.xmlEscape(paramValue)}</value>
127                                                         </param>
128                                                         """
129                     sbParams.append(paramsXml)
130                 }
131                 sbParams.append("</service-input-parameters>")
132             }
133             String siParamsXml = sbParams.toString()
134             if (siParamsXml == null)
135                 siParamsXml = ""
136             execution.setVariable("siParamsXml", siParamsXml)
137
138         } catch (BpmnError e) {
139             throw e;
140         } catch (Exception ex){
141             msg = "Exception in preProcessRequest " + ex.getMessage()
142             logger.error(msg)
143             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
144         }
145         logger.debug(" ***** Exit preProcessRequest *****",)
146     }
147
148     public void sequenceResource(DelegateExecution execution){
149         logger.debug(" ======== STARTED sequenceResource Process ======== ")
150         List<Resource> sequencedResourceList = new ArrayList<Resource>()
151         List<Resource> wanResources = new ArrayList<Resource>()
152
153         // get delete resource list and order list
154         List<Resource> delResourceList = execution.getVariable("deleteResourceList")
155
156         ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
157         String serviceModelName = serviceDecomposition.getModelInfo().getModelName();
158         
159         def resourceSequence = BPMNProperties.getResourceSequenceProp(serviceModelName)
160
161         if(resourceSequence != null) {
162             for (resourceType in resourceSequence.reverse()) {
163                 for (resource in delResourceList) {
164                     if (StringUtils.containsIgnoreCase(resource.getModelInfo().getModelName(), resourceType)) {
165                         sequencedResourceList.add(resource)
166
167                         if (resource instanceof NetworkResource) {
168                             wanResources.add(resource)
169                         }
170                     }
171                 }
172             }
173         }else {
174             //define sequenced resource list, we deploy vf first and then network and then ar
175             //this is defaule sequence
176             List<VnfResource> vnfResourceList = new ArrayList<VnfResource>()
177             List<AllottedResource> arResourceList = new ArrayList<AllottedResource>()
178             for (Resource rc : delResourceList) {
179                 if (rc instanceof VnfResource) {
180                     vnfResourceList.add(rc)
181                 } else if (rc instanceof NetworkResource) {
182                         wanResources.add(rc)
183                 } else if (rc instanceof AllottedResource) {
184                     arResourceList.add(rc)
185                 }
186             }
187
188             sequencedResourceList.addAll(arResourceList)
189             sequencedResourceList.addAll(wanResources)
190             sequencedResourceList.addAll(vnfResourceList)
191         }
192
193         String isContainsWanResource = wanResources.isEmpty() ? "false" : "true"
194         //if no networkResource, get SDNC config from properties file
195         if( "false".equals(isContainsWanResource)) {
196             String serviceNeedSDNC = "mso.workflow.custom." + serviceModelName + ".sdnc.need";
197             isContainsWanResource = BPMNProperties.getProperty(serviceNeedSDNC, isContainsWanResource)
198         }
199         execution.setVariable("isContainsWanResource", isContainsWanResource)
200         execution.setVariable("currentResourceIndex", 0)
201         execution.setVariable("sequencedResourceList", sequencedResourceList)
202         logger.debug("resourceSequence: " + resourceSequence)
203         logger.debug(" ======== END sequenceResource Process ======== ")
204     }
205
206     /**
207      * prepare delete parameters
208      */
209     public void preResourceDelete(DelegateExecution execution){
210         logger.debug(" ======== STARTED preResourceDelete Process ======== ")
211
212         List<Resource> sequencedResourceList = execution.getVariable("sequencedResourceList")
213
214         int currentIndex = execution.getVariable("currentResourceIndex")
215         if(sequencedResourceList != null && sequencedResourceList.size() > currentIndex){
216             Resource curResource = sequencedResourceList.get(currentIndex);
217
218             String resourceInstanceUUID = curResource.getResourceId()
219             String resourceTemplateUUID = curResource.getModelInfo().getModelUuid()
220             execution.setVariable("resourceInstanceId", resourceInstanceUUID)
221             execution.setVariable("currentResource", curResource)
222             logger.debug("Delete Resource Info resourceTemplate Id :" + resourceTemplateUUID + "  resourceInstanceId: "
223                     + resourceInstanceUUID + " resourceModelName: " + curResource.getModelInfo().getModelName())
224         }
225         else {
226             execution.setVariable("resourceInstanceId", "")
227         }
228
229         logger.debug(" ======== END preResourceDelete Process ======== ")
230     }
231
232
233     /**
234      * Execute delete workflow for resource
235      */
236     public void executeResourceDelete(DelegateExecution execution) {
237         logger.debug("======== Start executeResourceDelete Process ======== ")
238                 try {
239                 String requestId = execution.getVariable("msoRequestId")
240                 String serviceInstanceId = execution.getVariable("serviceInstanceId")
241                 String serviceType = execution.getVariable("serviceType")
242         
243                 String resourceInstanceId = execution.getVariable("resourceInstanceId")
244         
245                 Resource currentResource = execution.getVariable("currentResource")
246                 String action = "deleteInstance"
247                 JSONObject resourceRecipe = catalogDbUtils.getResourceRecipe(execution, currentResource.getModelInfo().getModelUuid(), action)
248                 String recipeUri = resourceRecipe.getString("orchestrationUri")
249                 int recipeTimeout = resourceRecipe.getInt("recipeTimeout")
250                 String recipeParamXsd = resourceRecipe.get("paramXSD")
251         
252         
253                 ResourceInput resourceInput = new ResourceInput();
254                 resourceInput.setServiceInstanceId(serviceInstanceId)
255                 resourceInput.setResourceInstanceName(currentResource.getResourceInstanceName())
256                 resourceInput.setResourceInstancenUuid(currentResource.getResourceId())
257                 resourceInput.setOperationId(execution.getVariable("operationId"))
258                 resourceInput.setOperationType(execution.getVariable("operationType"))
259                 String globalSubscriberId = execution.getVariable("globalSubscriberId") 
260                 resourceInput.setGlobalSubscriberId(globalSubscriberId)
261                 resourceInput.setResourceModelInfo(currentResource.getModelInfo());
262                     ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
263                         resourceInput.setServiceModelInfo(serviceDecomposition.getModelInfo());
264                 resourceInput.setServiceType(serviceType)
265         
266                 String recipeURL = BPMNProperties.getProperty("bpelURL", "http://so-bpmn-infra.onap:8081") + recipeUri
267
268             BpmnRestClient bpmnRestClient = new BpmnRestClient()
269                 HttpResponse resp = bpmnRestClient.post(recipeURL, requestId, recipeTimeout, action, serviceInstanceId, serviceType, resourceInput.toString(), recipeParamXsd)
270                 logger.debug(" ======== END executeResourceDelete Process ======== ")
271                 }catch(BpmnError b){
272                          logger.error("Rethrowing MSOWorkflowException")
273                          throw b
274                  }catch(Exception e){
275                          logger.error("Error occured within DoDeleteResourcesV1 executeResourceDelete method: " + e)
276                          exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Internal Error - Occured during DoDeleteResourcesV1 executeResourceDelete Catalog")
277                  }
278     }
279
280
281     public void parseNextResource(DelegateExecution execution){
282         logger.debug("======== Start parseNextResource Process ======== ")
283         def currentIndex = execution.getVariable("currentResourceIndex")
284         def nextIndex =  currentIndex + 1
285         execution.setVariable("currentResourceIndex", nextIndex)
286         List<String> sequencedResourceList = execution.getVariable("sequencedResourceList")
287         if(nextIndex >= sequencedResourceList.size()){
288             execution.setVariable("allResourceFinished", "true")
289         }else{
290             execution.setVariable("allResourceFinished", "false")
291         }
292         logger.debug("======== COMPLETED parseNextResource Process ======== ")
293     }
294     
295     public void prepareFinishedProgressForResource(DelegateExecution execution) {
296
297         String serviceInstanceId = execution.getVariable("serviceInstanceId")
298         String serviceType = execution.getVariable("serviceType")
299         String resourceInstanceId = execution.getVariable("resourceInstanceId")
300         Resource currentResource = execution.getVariable("currentResource")
301         String resourceCustomizationUuid = currentResource.getModelInfo().getModelCustomizationUuid()
302         String resourceModelName = currentResource.getModelInfo().getModelName()
303         String operationType = execution.getVariable("operationType")
304         String progress = "100"
305         String status = "finished"
306         String statusDescription = "The resource instance does not exist for " + resourceModelName
307         String operationId = execution.getVariable("operationId")
308
309         String body = """
310                 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
311                         xmlns:ns="http://org.onap.so/requestsdb">
312                         <soapenv:Header/>
313                 <soapenv:Body>
314                     <ns:updateResourceOperationStatus>
315                                <operType>${MsoUtils.xmlEscape(operationType)}</operType>
316                                <operationId>${MsoUtils.xmlEscape(operationId)}</operationId>
317                                <progress>${MsoUtils.xmlEscape(progress)}</progress>
318                                <resourceTemplateUUID>${MsoUtils.xmlEscape(resourceCustomizationUuid)}</resourceTemplateUUID>
319                                <serviceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceId>
320                                <status>${MsoUtils.xmlEscape(status)}</status>
321                                <statusDescription>${MsoUtils.xmlEscape(statusDescription)}</statusDescription>
322                     </ns:updateResourceOperationStatus>
323                 </soapenv:Body>
324                 </soapenv:Envelope>""";
325
326         def dbAdapterEndpoint = UrnPropertiesReader.getVariable("mso.adapters.openecomp.db.endpoint", execution)
327         execution.setVariable("CVFMI_dbAdapterEndpoint", dbAdapterEndpoint)
328         execution.setVariable("CVFMI_updateResOperStatusRequest", body)
329     }
330
331     public void prepareSDNCServiceDeactivateRequest (DelegateExecution execution) {
332         prepareSDNCServiceRequest (execution, "deactivate")
333     }
334     
335     public void prepareSDNCServiceDeleteRequest (DelegateExecution execution) {
336         prepareSDNCServiceRequest (execution, "delete")
337     }
338     
339     public void prepareSDNCServiceRequest (DelegateExecution execution, String svcAction) {
340         logger.debug(" ***** Started prepareSDNCServiceRequest for " + svcAction +  "*****")
341
342         try {
343             // get variables
344             String sdnc_svcAction = svcAction        
345             String sdncCallback = execution.getVariable("URN_mso_workflow_sdncadapter_callback")            
346             String hdrRequestId = execution.getVariable("msoRequestId")
347             String serviceInstanceId = execution.getVariable("serviceInstanceId")
348             String source = execution.getVariable("source")
349             String sdnc_service_id = serviceInstanceId
350             ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
351             String serviceType = execution.getVariable("serviceType")
352             String globalCustomerId = execution.getVariable("globalSubscriberId")
353             String serviceModelInvariantUuid = serviceDecomposition.getModelInfo().getModelInvariantUuid()
354             String serviceModelUuid = serviceDecomposition.getModelInfo().getModelUuid()
355             String serviceModelVersion = serviceDecomposition.getModelInfo().getModelVersion()
356             String serviceModelName = serviceDecomposition.getModelInfo().getModelName()
357
358             // 1. prepare assign topology via SDNC Adapter SUBFLOW call
359             String sndcTopologyDeleteRequest =
360                     """<aetgt:SDNCAdapterWorkflowRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
361                                                               xmlns:sdncadapter="http://org.onap.so/workflow/sdnc/adapter/schema/v1" 
362                                                               xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
363                                  <sdncadapter:RequestHeader>
364                                     <sdncadapter:RequestId>${MsoUtils.xmlEscape(hdrRequestId)}</sdncadapter:RequestId>
365                                     <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
366                                     <sdncadapter:SvcAction>${MsoUtils.xmlEscape(sdnc_svcAction)}</sdncadapter:SvcAction>
367                                     <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
368                                     <sdncadapter:CallbackUrl>sdncCallback</sdncadapter:CallbackUrl>
369                                     <sdncadapter:MsoAction>generic-resource</sdncadapter:MsoAction>
370                                  </sdncadapter:RequestHeader>
371                                  <sdncadapterworkflow:SDNCRequestData>
372                                      <request-information>
373                                         <request-id>${MsoUtils.xmlEscape(hdrRequestId)}</request-id>
374                                         <request-action>DeleteServiceInstance</request-action>
375                                         <source>${MsoUtils.xmlEscape(source)}</source>
376                                         <notification-url></notification-url>
377                                         <order-number></order-number>
378                                         <order-version></order-version>
379                                      </request-information>
380                                      <service-information>
381                                         <service-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-id>
382                                         <subscription-service-type>${MsoUtils.xmlEscape(serviceType)}</subscription-service-type>
383                                         <onap-model-information>
384                                              <model-invariant-uuid>${MsoUtils.xmlEscape(serviceModelInvariantUuid)}</model-invariant-uuid>
385                                              <model-uuid>${MsoUtils.xmlEscape(serviceModelUuid)}</model-uuid>
386                                              <model-version>${MsoUtils.xmlEscape(serviceModelVersion)}</model-version>
387                                              <model-name>${MsoUtils.xmlEscape(serviceModelName)}</model-name>
388                                         </onap-model-information>
389                                         <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
390                                         <global-customer-id>${MsoUtils.xmlEscape(globalCustomerId)}</global-customer-id>
391                                      </service-information>
392                                      <service-request-input>
393                                      </service-request-input>
394                                 </sdncadapterworkflow:SDNCRequestData>
395                              </aetgt:SDNCAdapterWorkflowRequest>""".trim()
396             
397             String sndcTopologyDeleteRequesAsString = utils.formatXml(sndcTopologyDeleteRequest)
398             logger.debug(sndcTopologyDeleteRequesAsString)
399             execution.setVariable("sdncAdapterWorkflowRequest", sndcTopologyDeleteRequesAsString)
400             logger.debug("sdncAdapterWorkflowRequest - " + "\n" +  sndcTopologyDeleteRequesAsString)
401
402         } catch (Exception ex) {
403             String exceptionMessage = " Bpmn error encountered in DoDeleteResourcesV1 flow. prepareSDNCServiceRequest() - " + ex.getMessage()
404             logger.debug(exceptionMessage)
405             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, exceptionMessage)
406
407         }
408        logger.debug("***** Exit prepareSDNCServiceRequest for " + svcAction +  "*****")
409         }
410 }