71026f1fa63eed545f366474cde8694a36b049e4
[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     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         AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(aaiObjectType, globalSubscriberId, serviceType, instanceId)
190         if (!getAAIClient().exists(resourceUri)) {
191             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
192         }
193         AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
194         return wrapper
195     }
196
197
198     /**
199      * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
200      */
201     void sendRequest2NSMFWF(DelegateExecution execution) {
202         LOGGER.trace("begin preRequestSend2NSMF")
203         try {
204             //url:/onap/so/infra/e2eServiceInstances/v3/{serviceInstanceId}"
205             def NSMF_endpoint = UrnPropertiesReader.getVariable("mso.infra.endpoint.url", execution)
206             String url = "${NSMF_endpoint}/e2eServiceInstances/v3/${execution.getVariable("e2eSliceServiceInstanceId")}"
207
208             String requestBody = """
209                 {
210                     "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
211                     "serviceType": "${execution.getVariable("serviceType")}"
212                 }
213             """
214             requestBody.replaceAll("\\s+", "")
215
216             String basicAuthValue =  UrnPropertiesReader.getVariable("mso.infra.endpoint.auth", execution)
217             HttpClient httpClient = new HttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
218             httpClient.addAdditionalHeader("Authorization", basicAuthValue)
219             httpClient.addAdditionalHeader("Accept", "application/json")
220             Response httpResponse = httpClient.delete(requestBody)
221             handleNSSMFWFResponse(httpResponse, execution)
222
223         } catch (BpmnError e) {
224             throw e
225         } catch (any) {
226             String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
227             LOGGER.error(msg)
228             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
229         }
230
231         LOGGER.trace("exit preRequestSend2NSMF")
232     }
233
234     /**
235      * prepare update operation status
236      * @param execution
237      */
238     private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
239         LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
240
241         int nsmfResponseCode = httpResponse.getStatus()
242         LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
243
244         if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
245             String nsmfResponse = httpResponse.readEntity(String.class)
246             def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
247             execution.setVariable("e2eOperationId", e2eOperationId)
248             execution.setVariable("progress","20")
249             execution.setVariable("operationContent","waiting nsmf service delete finished")
250
251             execution.setVariable("currentCycle",0)
252             execution.setVariable("isNSMFTimeOut", "no")
253             execution.setVariable("isNSMFWFRspSucceed","yes")
254         }
255         else
256         {
257             String serviceName = execution.getVariable("serviceInstanceName")
258             execution.setVariable("progress", "100")
259             execution.setVariable("result", "error")
260             execution.setVariable("operationContent", "terminate service failure.")
261             execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
262             execution.setVariable("isNSMFWFRspSucceed","no")
263             LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
264         }
265         setOperationStatus(execution)
266         LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
267     }
268
269     /**
270      * prepare to call sub process
271      * @param execution
272      */
273     void prepareCallCheckProcessStatus(DelegateExecution execution)
274     {
275         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
276
277         def successConditions = new ArrayList<>()
278         successConditions.add("finished")
279         execution.setVariable("successConditions", successConditions)
280
281         def errorConditions = new ArrayList<>()
282         errorConditions.add("error")
283         execution.setVariable("errorConditions", errorConditions)
284
285         execution.setVariable("processServiceType", "communication service")
286         execution.setVariable("subOperationType", "DELETE")
287         execution.setVariable("initProgress", 20)
288         execution.setVariable("endProgress",90)
289
290         execution.setVariable("timeOut", TIMEOUT)
291
292         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
293     }
294
295     /**
296      * delete communication profile from AAI
297      * @param execution
298      */
299     void delCSProfileFromAAI(DelegateExecution execution)
300     {
301         LOGGER.debug("start delete communication service profile from AAI")
302         String globalSubscriberId = execution.getVariable("globalSubscriberId")
303         String serviceType = execution.getVariable("serviceType")
304         String serviceInstanceId = execution.getVariable("serviceInstanceId")
305
306         String profileId
307         try
308         {
309             AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.COMMUNICATION_PROFILE_ALL, globalSubscriberId, serviceType, serviceInstanceId)
310             AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
311             Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
312             if(csProfilesOpt.isPresent()){
313                 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
314                 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
315                 profileId = csProfile ? csProfile.getProfileId() : ""
316             }
317             resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.COMMUNICATION_SERVICE_PROFILE, globalSubscriberId, serviceType, serviceInstanceId, profileId)
318             if (!getAAIClient().exists(resourceUri)) {
319                 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
320             }
321
322             getAAIClient().delete(resourceUri)
323             LOGGER.debug("end delete communication service profile from AAI")
324         }
325         catch (any)
326         {
327             String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
328             LOGGER.error(any.printStackTrace())
329             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
330         }
331
332     }
333
334     /**
335      * delete communication service from AAI
336      * @param execution
337      */
338     void delCSFromAAI(DelegateExecution execution)
339     {
340         try
341         {
342             LOGGER.debug("start delete communication service from AAI")
343             AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, execution.getVariable("globalSubscriberId"), execution.getVariable("serviceType"), execution.getVariable("serviceInstanceId"))
344             getAAIClient().delete(serviceInstanceUri)
345
346             execution.setVariable("progress", "100")
347             execution.setVariable("result", "finished")
348             execution.setVariable("operationContent", "CSMF completes service terminated.")
349             setOperationStatus(execution)
350             LOGGER.debug("end delete communication service from AAI")
351         }
352         catch (any)
353         {
354             LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
355             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
356         }
357     }
358
359     void sendSyncError(DelegateExecution execution)
360     {
361         LOGGER.debug("Starting sendSyncError")
362
363         try {
364             String errorMessage = "Sending Sync Error."
365             if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
366                 WorkflowException wfe = execution.getVariable("WorkflowException")
367                 errorMessage = wfe.getErrorMessage()
368             }
369
370             String buildworkflowException =
371                     """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
372                                         <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
373                                         <aetgt:ErrorCode>7000</aetgt:ErrorCode>
374                                    </aetgt:WorkflowException>"""
375
376             LOGGER.debug(buildworkflowException)
377             sendWorkflowResponse(execution, 500, buildworkflowException)
378
379         } catch (Exception ex) {
380             LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
381         }
382     }
383
384     /**
385      * prepare update operation status
386      * @param execution
387      */
388     void preFailedOperationStatus(DelegateExecution execution)
389     {
390         LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
391
392         execution.setVariable("progress", "100")
393         execution.setVariable("result", "error")
394         execution.setVariable("operationContent", "terminate service failure")
395
396         WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
397         String errorMessage = wfex.getErrorMessage()
398         errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
399         execution.setVariable("reason", errorMessage)
400         setOperationStatus(execution)
401
402         LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
403     }
404
405     /**
406      * prepare Operation status
407      * @param execution
408      * @param operationType
409      */
410     private void setOperationStatus(DelegateExecution execution)
411     {
412         OperationStatus operationStatus = new OperationStatus()
413         operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
414         operationStatus.setOperationId(execution.getVariable("operationId"))
415         operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
416         //interface not support update
417         operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
418         operationStatus.setResult(execution.getVariable("result"))
419         operationStatus.setProgress(execution.getVariable("progress"))
420         operationStatus.setOperationContent(execution.getVariable("operationContent"))
421         operationStatus.setReason(execution.getVariable("reason")?:"")
422         operationStatus.setOperation("DELETE")
423
424         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
425     }
426
427     void prepareFailureStatus(DelegateExecution execution)
428     {
429         execution.setVariable("result", "finished")
430         execution.setVariable("progress", "100")
431         execution.setVariable("operationContent", "terminate service failure.")
432         setOperationStatus(execution)
433         LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
434     }
435
436     /**
437      * check request json and save parameter to execution
438      * @param siRequest
439      * @param paraName
440      * @param isErrorException
441      * @param execution
442      */
443     private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
444     {
445         String msg = ""
446         String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
447         if (isBlank(paramValue)) {
448             msg = "Input ${paraName} is null"
449             LOGGER.error(msg)
450             if(isErrorException)
451             {
452                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
453             }
454
455         } else {
456             execution.setVariable(paraName, paramValue)
457         }
458     }
459
460 }