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