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