0c676b5589b28a2119ded830ff15143086c8d22e
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DoDeleteServiceInstance.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.scripts
24
25 import static org.apache.commons.lang3.StringUtils.*;
26
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.onap.aai.domain.yang.ServiceInstance
31 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
32 import org.onap.so.bpmn.common.scripts.ExceptionUtil
33 import org.onap.so.bpmn.common.scripts.MsoUtils
34 import org.onap.so.bpmn.common.scripts.SDNCAdapterUtils
35 import org.onap.so.bpmn.core.UrnPropertiesReader;
36 import org.onap.so.bpmn.core.WorkflowException
37 import org.onap.so.bpmn.core.json.JsonUtils
38 import org.onap.so.client.aai.AAIObjectType
39 import org.onap.so.client.aai.AAIResourcesClient
40 import org.onap.so.client.aai.entities.AAIResultWrapper
41 import org.onap.so.client.aai.entities.uri.AAIResourceUri
42 import org.onap.so.client.aai.entities.uri.AAIUriFactory
43 import org.slf4j.Logger
44 import org.slf4j.LoggerFactory
45 import org.springframework.web.util.UriUtils;
46
47 import groovy.json.*
48
49 /**
50  * This groovy class supports the <class>DoDeleteServiceInstance.bpmn</class> process.
51  *
52  * Inputs:
53  * @param - msoRequestId
54  * @param - globalSubscriberId - O
55  * @param - subscriptionServiceType - O
56  * @param - serviceInstanceId
57  * @param - serviceInstanceName - O
58  * @param - serviceModelInfo - O
59  * @param - productFamilyId
60  * @param - serviceInputParams (should contain aic_zone for serviceTypes TRANSPORT,ATM)
61  * @param - sdncVersion
62  * @param - failNotFound - TODO
63  * @param - serviceInputParams - TODO
64  *
65  * Outputs:
66  * @param - WorkflowException
67  *
68  * Rollback - Deferred
69  */
70 public class DoDeleteServiceInstance extends AbstractServiceTaskProcessor {
71     private static final Logger logger = LoggerFactory.getLogger( DoDeleteServiceInstance.class);
72
73         String Prefix="DDELSI_"
74         ExceptionUtil exceptionUtil = new ExceptionUtil()
75         JsonUtils jsonUtil = new JsonUtils()
76
77         public void preProcessRequest (DelegateExecution execution) {
78
79                 logger.trace("preProcessRequest ")
80                 String msg = ""
81
82                 try {
83                         String requestId = execution.getVariable("msoRequestId")
84                         execution.setVariable("prefix",Prefix)
85
86                         //Inputs
87                         //requestDetails.subscriberInfo. for AAI GET & PUT & SDNC assignToplology
88                         String globalSubscriberId = execution.getVariable("globalSubscriberId") //globalCustomerId
89                         if (globalSubscriberId == null)
90                         {
91                                 execution.setVariable("globalSubscriberId", "")
92                         }
93
94                         //requestDetails.requestParameters. for AAI PUT & SDNC assignTopology
95                         String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
96                         if (subscriptionServiceType == null)
97                         {
98                                 execution.setVariable("subscriptionServiceType", "")
99                         }
100
101                         //Generated in parent for AAI PUT
102                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
103                         if (isBlank(serviceInstanceId)){
104                                 msg = "Input serviceInstanceId is null"
105                                 logger.debug(msg)
106                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
107                         }
108
109                         String sdncCallbackUrl = UrnPropertiesReader.getVariable('mso.workflow.sdncadapter.callback',execution)
110                         if (isBlank(sdncCallbackUrl)) {
111                                 msg = "mso.workflow.sdncadapter.callback is null"
112                                 logger.debug(msg)
113                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
114                         }
115                         execution.setVariable("sdncCallbackUrl", sdncCallbackUrl)
116                         logger.debug("SDNC Callback URL: " + sdncCallbackUrl)
117
118                         StringBuilder sbParams = new StringBuilder()
119                         Map<String, String> paramsMap = execution.getVariable("serviceInputParams")
120                         if (paramsMap != null)
121                         {
122                                 sbParams.append("<service-input-parameters>")
123                                 for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
124                                         String paramsXml
125                                         String paramName = entry.getKey()
126                                         String paramValue = entry.getValue()
127                                         paramsXml =
128                                                         """     <param>
129                                                         <name>${MsoUtils.xmlEscape(paramName)}</name>
130                                                         <value>${MsoUtils.xmlEscape(paramValue)}</value>
131                                                         </param>
132                                                         """
133                                         sbParams.append(paramsXml)
134                                 }
135                                 sbParams.append("</service-input-parameters>")
136                         }
137                         String siParamsXml = sbParams.toString()
138                         if (siParamsXml == null)
139                                 siParamsXml = ""
140                         execution.setVariable("siParamsXml", siParamsXml)
141
142                 } catch (BpmnError e) {
143                         throw e;
144                 } catch (Exception ex){
145                         msg = "Exception in preProcessRequest " + ex.getMessage()
146                         logger.debug(msg)
147                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
148                 }
149                 logger.trace("Exit preProcessRequest ")
150         }
151
152         public void preProcessSDNCDelete (DelegateExecution execution) {
153
154                 logger.trace("preProcessSDNCDelete ")
155                 String msg = ""
156
157                 try {
158                         def serviceInstanceId = execution.getVariable("serviceInstanceId") ?: ""
159                         def serviceInstanceName = execution.getVariable("serviceInstanceName") ?: ""
160                         def callbackURL = execution.getVariable("sdncCallbackUrl") ?: ""
161                         def requestId = execution.getVariable("msoRequestId") ?: ""
162                         def serviceId = execution.getVariable("productFamilyId") ?: ""
163                         def subscriptionServiceType = execution.getVariable("subscriptionServiceType") ?: ""
164                         def globalSubscriberId = execution.getVariable("globalSubscriberId") ?: "" //globalCustomerId
165
166                         String serviceModelInfo = execution.getVariable("serviceModelInfo") ?: ""
167                         def modelInvariantUuid = ""
168                         def modelVersion = ""
169                         def modelUuid = ""
170                         def modelName = ""
171                         if (!isBlank(serviceModelInfo))
172                         {
173                                 modelInvariantUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelInvariantUuid") ?: ""
174                                 modelVersion = jsonUtil.getJsonValue(serviceModelInfo, "modelVersion") ?: ""
175                                 modelUuid = jsonUtil.getJsonValue(serviceModelInfo, "modelUuid") ?: ""
176                                 modelName = jsonUtil.getJsonValue(serviceModelInfo, "modelName") ?: ""
177
178                         }
179
180                         def siParamsXml = execution.getVariable("siParamsXml") ?: ""
181                         def msoAction = ""
182                         // special URL for SDNW, msoAction helps set diff url in SDNCA
183                         if("TRANSPORT".equalsIgnoreCase(execution.getVariable("serviceType")))
184                         {
185                                 msoAction = "TRANSPORT"
186                         }
187
188                         def sdncRequestId = UUID.randomUUID().toString()
189
190                         String sdncDelete =
191                                         """<sdncadapterworkflow:SDNCAdapterWorkflowRequest xmlns:ns5="http://org.onap/so/request/types/v1"
192                                                                                                         xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1"
193                                                                                                         xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
194                                    <sdncadapter:RequestHeader>
195                                                         <sdncadapter:RequestId>${MsoUtils.xmlEscape(sdncRequestId)}</sdncadapter:RequestId>
196                                                         <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
197                                                         <sdncadapter:SvcAction>delete</sdncadapter:SvcAction>
198                                                         <sdncadapter:SvcOperation>service-topology-operation</sdncadapter:SvcOperation>
199                                                         <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackURL)}</sdncadapter:CallbackUrl>
200                                                         <sdncadapter:MsoAction>${MsoUtils.xmlEscape(msoAction)}</sdncadapter:MsoAction>
201                                         </sdncadapter:RequestHeader>
202                                 <sdncadapterworkflow:SDNCRequestData>
203                                         <request-information>
204                                                 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
205                                                 <source>MSO</source>
206                                                 <notification-url/>
207                                                 <order-number/>
208                                                 <order-version/>
209                                                 <request-action>DeleteServiceInstance</request-action>
210                                         </request-information>
211                                         <service-information>
212                                                 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
213                                                 <subscription-service-type>${MsoUtils.xmlEscape(subscriptionServiceType)}</subscription-service-type>
214                                                 <onap-model-information>
215                                                  <model-invariant-uuid>${MsoUtils.xmlEscape(modelInvariantUuid)}</model-invariant-uuid>
216                                                  <model-uuid>${MsoUtils.xmlEscape(modelUuid)}</model-uuid>
217                                                  <model-version>${MsoUtils.xmlEscape(modelVersion)}</model-version>
218                                                  <model-name>${MsoUtils.xmlEscape(modelName)}</model-name>
219                                             </onap-model-information>
220                                                 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
221                                                 <subscriber-name/>
222                                                 <global-customer-id>${MsoUtils.xmlEscape(globalSubscriberId)}</global-customer-id>
223                                         </service-information>
224                                         <service-request-input>
225                                                 <service-instance-name>${MsoUtils.xmlEscape(serviceInstanceName)}</service-instance-name>
226                                                 ${siParamsXml}
227                                         </service-request-input>
228                                 </sdncadapterworkflow:SDNCRequestData>
229                                 </sdncadapterworkflow:SDNCAdapterWorkflowRequest>"""
230
231                         sdncDelete = utils.formatXml(sdncDelete)
232                         def sdncRequestId2 = UUID.randomUUID().toString()
233                         String sdncDeactivate = sdncDelete.replace(">delete<", ">deactivate<").replace(">${sdncRequestId}<", ">${sdncRequestId2}<")
234                         execution.setVariable("sdncDelete", sdncDelete)
235                         execution.setVariable("sdncDeactivate", sdncDeactivate)
236                         logger.debug("sdncDeactivate:\n" + sdncDeactivate)
237                         logger.debug("sdncDelete:\n" + sdncDelete)
238
239                 } catch (BpmnError e) {
240                         throw e;
241                 } catch(Exception ex) {
242                         msg = "Exception in preProcessSDNCDelete. " + ex.getMessage()
243                         logger.debug(msg)
244                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "Exception Occured in preProcessSDNCDelete.\n" + ex.getMessage())
245                 }
246                 logger.debug(" *****Exit preProcessSDNCDelete *****")
247         }
248
249         public void postProcessSDNCDelete(DelegateExecution execution, String response, String method) {
250
251
252                 logger.trace("postProcessSDNC " + method + " ")
253                 String msg = ""
254
255                 try {
256                         WorkflowException workflowException = execution.getVariable("WorkflowException")
257                         boolean successIndicator = execution.getVariable("SDNCA_SuccessIndicator")
258                         logger.debug("SDNCResponse: " + response)
259                         logger.debug("workflowException: " + workflowException)
260
261                         SDNCAdapterUtils sdncAdapterUtils = new SDNCAdapterUtils()
262                         sdncAdapterUtils.validateSDNCResponse(execution, response, workflowException, successIndicator)
263
264                         if(execution.getVariable(Prefix + 'sdncResponseSuccess') == true){
265                                 logger.debug("Good response from SDNC Adapter for service-instance " + method + "response:\n" + response)
266
267                         }else{
268                                 msg = "Bad Response from SDNC Adapter for service-instance " + method
269                                 logger.debug(msg)
270                                 exceptionUtil.buildAndThrowWorkflowException(execution, 3500, msg)
271                         }
272                 } catch (BpmnError e) {
273                         throw e;
274                 } catch(Exception ex) {
275                         msg = "Exception in postProcessSDNC " + method + " Exception:" + ex.getMessage()
276                         logger.debug(msg)
277                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
278                 }
279                 logger.trace("Exit postProcessSDNC " + method + " ")
280         }
281
282         /**
283          * Gets the service instance uri from aai
284          */
285         public void getServiceInstance(DelegateExecution execution) {
286                 logger.trace("getServiceInstance ")
287                 try {
288                         String serviceInstanceId = execution.getVariable('serviceInstanceId')
289
290                         AAIResourcesClient resourceClient = new AAIResourcesClient()
291                         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId)
292
293                         if(resourceClient.exists(uri)){
294                                 execution.setVariable("GENGS_siResourceLink", uri.build().toString())
295                                 Map<String, String> keys = uri.getURIKeys()
296                                 String  globalSubscriberId = execution.getVariable("globalSubscriberId")
297                                 if(isBlank(globalSubscriberId)){
298                                         globalSubscriberId = keys.get("global-customer-id")
299                                         execution.setVariable("globalSubscriberId", globalSubscriberId)
300                                 }
301
302                                 //Extract Service Type if not provided on request
303                                 String subscriptionServiceType = execution.getVariable("subscriptionServiceType")
304                                 if(isBlank(subscriptionServiceType)){
305                                         String serviceTypeEncoded = keys.get("service-type") //TODO will this produce as already decoded?
306                                         subscriptionServiceType = UriUtils.decode(serviceTypeEncoded, "UTF-8")
307                                         execution.setVariable("subscriptionServiceType", subscriptionServiceType)
308                                 }
309
310                                 AAIResultWrapper wrapper = resourceClient.get(uri)
311                                 if(wrapper.getRelationships().isPresent()){
312                                         List<AAIResourceUri> uriList = wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.ALLOTTED_RESOURCE)
313                                         uriList.addAll(wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.GENERIC_VNF))
314                                         uriList.addAll(wrapper.getRelationships().get().getRelatedAAIUris(AAIObjectType.L3_NETWORK))
315
316                                         if(uriList.isEmpty()){
317                                                 Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
318                                                 String orchestrationStatus = si.get().getOrchestrationStatus()
319                                                 String serviceType = si.get().getServiceType()
320                                                 execution.setVariable("serviceType", serviceType)
321                                                 execution.setVariable("serviceRole", si.get().getServiceRole())
322
323                                                 if("TRANSPORT".equalsIgnoreCase(serviceType)){
324                                                         if("PendingDelete".equals(orchestrationStatus)){
325                                                                 execution.setVariable("skipDeactivate", true)
326                                                         }else{
327                                                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "ServiceInstance of type TRANSPORT must in PendingDelete status to allow Delete. Orchestration-status: " + orchestrationStatus)
328                                                         }
329                                                 }
330
331                                                 String svcTypes = UrnPropertiesReader.getVariable("sdnc.si.svc.types",execution) ?: ""
332                                                 List<String> svcList = Arrays.asList(svcTypes.split("\\s*,\\s*"));
333                                                 boolean isSdncService= false
334                                                 for(String listEntry : svcList){
335                                                         if(listEntry.equalsIgnoreCase(serviceType)){
336                                                                 isSdncService = true
337                                                                 break;
338                                                         }
339                                                 }
340                                                 execution.setVariable("sendToSDNC", true)
341                                                 if(execution.getVariable("sdncVersion").equals("1610")){
342                                                         if(!isSdncService){
343                                                                 execution.setVariable("sendToSDNC", false)
344                                                         }
345                                                 }
346
347                                         }else{
348                                                 execution.setVariable("siInUse", true)
349                                                 logger.debug("Stopped deleting Service Instance, it has dependencies")
350                                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "Stopped deleting Service Instance, it has dependencies")
351                                         }
352                                 }
353                         }else{
354                                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, "ServiceInstance not found in aai")
355                         }
356
357                 }catch(BpmnError e) {
358                         throw e;
359                 }catch (Exception ex){
360                         String msg = "Exception in getServiceInstance. " + ex.getMessage()
361                         logger.debug(msg)
362                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
363                 }
364         }
365
366         /**
367          * Deletes the service instance in aai
368          */
369         public void deleteServiceInstance(DelegateExecution execution) {
370                 logger.trace("Entered deleteServiceInstance")
371                 try {
372                         String globalCustId = execution.getVariable("globalSubscriberId")
373                         String serviceType = execution.getVariable("subscriptionServiceType")
374                         String serviceInstanceId = execution.getVariable("serviceInstanceId")
375
376                         AAIResourcesClient resourceClient = new AAIResourcesClient();
377                         AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalCustId, serviceType, serviceInstanceId)
378                         resourceClient.delete(serviceInstanceUri)
379
380                         logger.trace("Exited deleteServiceInstance")
381                 }catch(Exception e){
382                         logger.debug("Error occured within deleteServiceInstance method: " + e)
383                         exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during deleteServiceInstance from aai")
384                 }
385         }
386
387 }