d00f349690cbc64cf8a9a6484156c9798bd0f96c
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / DeleteCommunicationService.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2019, CMCC Technologies Co., Ltd.
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.onap.so.bpmn.infrastructure.scripts
21
22 import org.onap.aaiclient.client.aai.entities.uri.AAISimpleUri
23
24 import static org.apache.commons.lang3.StringUtils.isBlank
25 import javax.ws.rs.NotFoundException
26 import javax.ws.rs.core.Response
27 import org.camunda.bpm.engine.delegate.BpmnError
28 import org.camunda.bpm.engine.delegate.DelegateExecution
29 import org.onap.aai.domain.yang.CommunicationServiceProfile
30 import org.onap.aai.domain.yang.CommunicationServiceProfiles
31 import org.onap.aai.domain.yang.Relationship
32 import org.onap.aai.domain.yang.ServiceInstance
33 import org.onap.aaiclient.client.aai.AAIObjectName
34 import org.onap.aaiclient.client.aai.AAIObjectType
35 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
36 import org.onap.aaiclient.client.aai.entities.uri.AAIPluralResourceUri
37 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
38 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
39 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
40 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
41 import org.onap.logging.filter.base.ONAPComponents
42 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
43 import org.onap.so.bpmn.common.scripts.ExceptionUtil
44 import org.onap.so.bpmn.common.scripts.MsoUtils
45 import org.onap.so.bpmn.common.scripts.RequestDBUtil
46 import org.onap.so.bpmn.core.UrnPropertiesReader
47 import org.onap.so.bpmn.core.WorkflowException
48 import org.onap.so.bpmn.core.json.JsonUtils
49 import org.onap.so.client.HttpClient
50 import org.onap.so.db.request.beans.OperationStatus
51 import org.slf4j.Logger
52 import org.slf4j.LoggerFactory
53
54 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
55     private final String PREFIX ="DeleteCommunicationService"
56     private final Long TIMEOUT = 60 * 60 * 1000
57
58     ExceptionUtil exceptionUtil = new ExceptionUtil()
59     JsonUtils jsonUtil = new JsonUtils()
60     private RequestDBUtil requestDBUtil = new RequestDBUtil()
61     private static final Logger LOGGER = LoggerFactory.getLogger(DeleteCommunicationService.class)
62
63     @Override
64     void preProcessRequest(DelegateExecution execution) {
65         execution.setVariable("prefix",PREFIX)
66         String msg = ""
67
68         LOGGER.trace("Starting preProcessRequest")
69
70         try {
71             // check for incoming json message/input
72             String siRequest = execution.getVariable("bpmnRequest")
73             String requestId = execution.getVariable("mso-request-id")
74             execution.setVariable("msoRequestId", requestId)
75             execution.setVariable("operationType", "DELETE")
76
77             //communication service id
78             String serviceInstanceId = execution.getVariable("serviceInstanceId")
79             if (isBlank(serviceInstanceId)) {
80                 msg = "communication-service id is null"
81                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
82             }
83
84             LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
85
86             //requestParameters
87             checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
88             checkAndSetRequestParam(siRequest,"serviceType",false,execution)
89             checkAndSetRequestParam(siRequest,"operationId",false,execution)
90
91         } catch (BpmnError e) {
92             throw e
93         } catch (any) {
94             msg = "Exception in preProcessRequest " + any.getCause()
95             LOGGER.debug(msg)
96             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
97         }
98         LOGGER.trace("Exit preProcessRequest")
99     }
100
101
102     /**
103      * prepare update operation status
104      * @param execution
105      */
106     void preInitUpdateOperationStatus(DelegateExecution execution){
107         LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
108         try{
109             execution.setVariable("result","processing")
110             execution.setVariable("progress","0")
111             execution.setVariable("operationContent","delete communication service operation start")
112             setOperationStatus(execution)
113
114         }catch(Exception e){
115             LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
116             execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
117         }
118         LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
119     }
120
121     /**
122      * send sync response
123      * @param execution
124      */
125     void sendSyncResponse(DelegateExecution execution) {
126         LOGGER.debug("Begin sendSyncResponse")
127
128         try {
129             String operationId = execution.getVariable("operationId")
130             String syncResponse = """{"operationId":"${operationId}"}""".trim()
131             sendWorkflowResponse(execution, 202, syncResponse)
132
133         } catch (Exception ex) {
134             String msg  = "Exception in sendSyncResponse: " + ex.getMessage()
135             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
136         }
137         LOGGER.debug("Exit sendSyncResponse")
138     }
139
140     /**
141      * query CommunicationSerive from AAI
142      * save e2eslice-service instance id and service name
143      * @param execution
144      */
145     void queryCommunicationSeriveFromAAI(DelegateExecution execution)
146     {
147         LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
148         String serviceInstanceId = execution.getVariable("serviceInstanceId")
149
150         String errorMsg = "query communication service from aai failed"
151         AAIResultWrapper wrapper = queryAAI(execution, Types.SERVICE_INSTANCE, serviceInstanceId, errorMsg)
152         Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
153         if(si.isPresent())
154         {
155             String serviceInstName = si.get()?.getServiceInstanceName()
156             String e2eSliceServiceInstId
157             if(si.isPresent())
158             {
159                 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
160                 for (Relationship relationship : relationshipList)
161                 {
162                     String relatedTo = relationship.getRelatedTo()
163                     if (relatedTo == "service-instance")
164                     {
165                         String relatedLink = relationship.getRelatedLink()?:""
166                         e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
167                         break
168                     }
169                 }
170             }
171             execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
172             execution.setVariable("serviceInstanceName", serviceInstName ?: "")
173             LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
174         }
175         LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
176     }
177
178     /**
179      * query AAI
180      * @param execution
181      * @param aaiObjectName
182      * @param instanceId
183      * @return AAIResultWrapper
184      */
185     private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
186     {
187         String globalSubscriberId = execution.getVariable("globalSubscriberId")
188         String serviceType = execution.getVariable("serviceType")
189
190         AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId))
191         if (!getAAIClient().exists(resourceUri)) {
192             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
193         }
194         AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
195         return wrapper
196     }
197
198
199     /**
200      * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
201      */
202     void sendRequest2NSMFWF(DelegateExecution execution) {
203         LOGGER.debug("begin preRequestSend2NSMF")
204         try {
205             //url:/onap/so/infra/e2eServiceInstances/v3/{serviceInstanceId}"
206             def NSMF_endpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
207             String url = "${NSMF_endpoint}/e2eServiceInstances/v3/${execution.getVariable("e2eSliceServiceInstanceId")}"
208
209             String requestBody = """
210                 {
211                     "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
212                     "serviceType": "${execution.getVariable("serviceType")}"
213                 }
214             """
215             requestBody.replaceAll("\\s+", "")
216
217             String msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
218             String basicAuth =  UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
219 //            String basicAuthValue = utils.encrypt(basicAuth, msoKey)
220 //            String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
221
222             HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
223 //            httpClient.addAdditionalHeader("Authorization", encodeString)
224             httpClient.addAdditionalHeader("Authorization", basicAuth)
225             httpClient.addAdditionalHeader("Accept", "application/json")
226             Response httpResponse = httpClient.delete(requestBody)
227             handleNSSMFWFResponse(httpResponse, execution)
228
229         } catch (BpmnError e) {
230             throw e
231         } catch (any) {
232             String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
233             LOGGER.error(msg)
234             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
235         }
236
237         LOGGER.debug("exit preRequestSend2NSMF")
238     }
239
240     /**
241      * prepare update operation status
242      * @param execution
243      */
244     private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
245         LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
246
247         int nsmfResponseCode = httpResponse.getStatus()
248         LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
249
250         if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
251             String nsmfResponse = httpResponse.readEntity(String.class)
252             def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
253             execution.setVariable("e2eOperationId", e2eOperationId)
254             execution.setVariable("progress","20")
255             execution.setVariable("operationContent","waiting nsmf service delete finished")
256
257             execution.setVariable("currentCycle",0)
258             execution.setVariable("isNSMFTimeOut", "no")
259             execution.setVariable("isNSMFWFRspSucceed","yes")
260         }
261         else
262         {
263             String serviceName = execution.getVariable("serviceInstanceName")
264             execution.setVariable("progress", "100")
265             execution.setVariable("result", "error")
266             execution.setVariable("operationContent", "terminate service failure.")
267             execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
268             execution.setVariable("isNSMFWFRspSucceed","no")
269             LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
270         }
271         setOperationStatus(execution)
272         LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
273     }
274
275     /**
276      * prepare to call sub process
277      * @param execution
278      */
279     void prepareCallCheckProcessStatus(DelegateExecution execution)
280     {
281         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
282
283         def successConditions = new ArrayList<>()
284         successConditions.add("finished")
285         execution.setVariable("successConditions", successConditions)
286
287         def errorConditions = new ArrayList<>()
288         errorConditions.add("error")
289         execution.setVariable("errorConditions", errorConditions)
290
291         execution.setVariable("processServiceType", "communication service")
292         execution.setVariable("subOperationType", "DELETE")
293         execution.setVariable("initProgress", 20)
294         execution.setVariable("endProgress",90)
295
296         execution.setVariable("timeOut", TIMEOUT)
297
298         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
299     }
300
301     /**
302      * delete communication profile from AAI
303      * @param execution
304      */
305     void delCSProfileFromAAI(DelegateExecution execution)
306     {
307         LOGGER.debug("start delete communication service profile from AAI")
308         String globalSubscriberId = execution.getVariable("globalSubscriberId")
309         String serviceType = execution.getVariable("serviceType")
310         String serviceInstanceId = execution.getVariable("serviceInstanceId")
311
312         String profileId
313         try
314         {
315             AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
316             AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
317             Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
318             if(csProfilesOpt.isPresent()){
319                 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
320                 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
321                 profileId = csProfile ? csProfile.getProfileId() : ""
322             }
323             AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
324             if (!getAAIClient().exists(profileUri)) {
325                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
326             }
327
328             getAAIClient().delete(profileUri)
329             LOGGER.debug("end delete communication service profile from AAI")
330         }
331         catch (any)
332         {
333             String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
334             LOGGER.error(any.printStackTrace())
335             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
336         }
337
338     }
339
340     /**
341      * delete communication service from AAI
342      * @param execution
343      */
344     void delCSFromAAI(DelegateExecution execution)
345     {
346         try
347         {
348             LOGGER.debug("start delete communication service from AAI")
349             AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
350             getAAIClient().delete(serviceInstanceUri)
351
352             execution.setVariable("progress", "100")
353             execution.setVariable("result", "finished")
354             execution.setVariable("operationContent", "CSMF completes service terminated.")
355             setOperationStatus(execution)
356             LOGGER.debug("end delete communication service from AAI")
357         }
358         catch (any)
359         {
360             LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
361             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
362         }
363     }
364
365     void sendSyncError(DelegateExecution execution)
366     {
367         LOGGER.debug("Starting sendSyncError")
368
369         try {
370             String errorMessage = "Sending Sync Error."
371             if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
372                 WorkflowException wfe = execution.getVariable("WorkflowException")
373                 errorMessage = wfe.getErrorMessage()
374             }
375
376             String buildworkflowException =
377                     """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
378                                         <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
379                                         <aetgt:ErrorCode>7000</aetgt:ErrorCode>
380                                    </aetgt:WorkflowException>"""
381
382             LOGGER.debug(buildworkflowException)
383             sendWorkflowResponse(execution, 500, buildworkflowException)
384
385         } catch (Exception ex) {
386             LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
387         }
388     }
389
390     /**
391      * prepare update operation status
392      * @param execution
393      */
394     void preFailedOperationStatus(DelegateExecution execution)
395     {
396         LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
397
398         execution.setVariable("progress", "100")
399         execution.setVariable("result", "error")
400         execution.setVariable("operationContent", "terminate service failure")
401
402         WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
403         String errorMessage = wfex.getErrorMessage()
404         errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
405         execution.setVariable("reason", errorMessage)
406         setOperationStatus(execution)
407
408         LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
409     }
410
411     /**
412      * prepare Operation status
413      * @param execution
414      * @param operationType
415      */
416     private void setOperationStatus(DelegateExecution execution)
417     {
418         OperationStatus operationStatus = new OperationStatus()
419         operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
420         operationStatus.setOperationId(execution.getVariable("operationId"))
421         operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
422         //interface not support update
423         operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
424         operationStatus.setResult(execution.getVariable("result"))
425         operationStatus.setProgress(execution.getVariable("progress"))
426         operationStatus.setOperationContent(execution.getVariable("operationContent"))
427         operationStatus.setReason(execution.getVariable("reason")?:"")
428         operationStatus.setOperation("DELETE")
429
430         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
431     }
432
433     void prepareFailureStatus(DelegateExecution execution)
434     {
435         execution.setVariable("result", "finished")
436         execution.setVariable("progress", "100")
437         execution.setVariable("operationContent", "terminate service failure.")
438         setOperationStatus(execution)
439         LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
440     }
441
442     /**
443      * check request json and save parameter to execution
444      * @param siRequest
445      * @param paraName
446      * @param isErrorException
447      * @param execution
448      */
449     private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
450     {
451         String msg = ""
452         String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
453         if (isBlank(paramValue)) {
454             msg = "Input ${paraName} is null"
455             LOGGER.error(msg)
456             if(isErrorException)
457             {
458                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
459             }
460
461         } else {
462             execution.setVariable(paraName, paramValue)
463         }
464     }
465
466 }