2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  # Copyright (c) 2019, CMCC Technologies Co., Ltd.
 
   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
 
  11  #       http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  20 package org.onap.so.bpmn.infrastructure.scripts
 
  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
 
  48 import javax.ws.rs.NotFoundException
 
  49 import javax.ws.rs.core.Response
 
  51 import static org.apache.commons.lang3.StringUtils.isBlank
 
  53 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
 
  54     private final String PREFIX ="DeleteCommunicationService"
 
  55     private final Long TIMEOUT = 60 * 60 * 1000
 
  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)
 
  63     void preProcessRequest(DelegateExecution execution) {
 
  64         execution.setVariable("prefix",PREFIX)
 
  67         LOGGER.trace("Starting preProcessRequest")
 
  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")
 
  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)
 
  83             LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
 
  86             checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
 
  87             checkAndSetRequestParam(siRequest,"serviceType",false,execution)
 
  88             checkAndSetRequestParam(siRequest,"operationId",false,execution)
 
  90         } catch (BpmnError e) {
 
  93             msg = "Exception in preProcessRequest " + any.getCause()
 
  95             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
  97         LOGGER.trace("Exit preProcessRequest")
 
 102      * prepare update operation status
 
 105     void preInitUpdateOperationStatus(DelegateExecution execution){
 
 106         LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
 
 108             execution.setVariable("result","processing")
 
 109             execution.setVariable("progress","0")
 
 110             execution.setVariable("operationContent","delete communication service operation start")
 
 111             setOperationStatus(execution)
 
 114             LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
 
 115             execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
 
 117         LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
 
 124     void sendSyncResponse(DelegateExecution execution) {
 
 125         LOGGER.debug("Begin sendSyncResponse")
 
 128             String operationId = execution.getVariable("operationId")
 
 129             String syncResponse = """{"operationId":"${operationId}"}""".trim()
 
 130             sendWorkflowResponse(execution, 202, syncResponse)
 
 132         } catch (Exception ex) {
 
 133             String msg  = "Exception in sendSyncResponse: " + ex.getMessage()
 
 134             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 136         LOGGER.debug("Exit sendSyncResponse")
 
 140      * query CommunicationSerive from AAI
 
 141      * save e2eslice-service instance id and service name
 
 144     private void queryCommunicationSeriveFromAAI(DelegateExecution execution)
 
 146         LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
 
 147         String serviceInstanceId = execution.getVariable("serviceInstanceId")
 
 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)
 
 154             String serviceInstName = si.get()?.getServiceInstanceName()
 
 155             String e2eSliceServiceInstId
 
 158                 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
 
 159                 for (Relationship relationship : relationshipList)
 
 161                     String relatedTo = relationship.getRelatedTo()
 
 162                     if (relatedTo == "service-instance")
 
 164                         String relatedLink = relationship.getRelatedLink()?:""
 
 165                         e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
 
 170             execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
 
 171             execution.setVariable("serviceInstanceName", serviceInstName ?: "")
 
 172             LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
 
 174         LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
 
 180      * @param aaiObjectType
 
 182      * @return AAIResultWrapper
 
 184     private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectType aaiObjectType, String instanceId, String errorMsg)
 
 186         String globalSubscriberId = execution.getVariable("globalSubscriberId")
 
 187         String serviceType = execution.getVariable("serviceType")
 
 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)
 
 194         AAIResultWrapper wrapper = resourceClient.get(resourceUri, NotFoundException.class)
 
 200      * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
 
 202     void sendRequest2NSMFWF(DelegateExecution execution) {
 
 203         LOGGER.trace("begin preRequestSend2NSMF")
 
 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")}"
 
 209             String requestBody = """
 
 211                     "globalSubscriberId": "${execution.getVariable("globalSubscriberId")}",
 
 212                     "serviceType": "${execution.getVariable("serviceType")}"
 
 215             requestBody.replaceAll("\\s+", "")
 
 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)
 
 224         } catch (BpmnError e) {
 
 227             String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
 
 229             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
 
 232         LOGGER.trace("exit preRequestSend2NSMF")
 
 236      * prepare to call sub process
 
 239     void prepareCallCheckProcessStatus(DelegateExecution execution)
 
 241         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
 
 243         def successConditions = new ArrayList<>()
 
 244         successConditions.add("finished")
 
 245         execution.setVariable("successConditions", successConditions)
 
 247         def errorConditions = new ArrayList<>()
 
 248         errorConditions.add("error")
 
 249         execution.setVariable("errorConditions", errorConditions)
 
 251         execution.setVariable("processServiceType", "communication service")
 
 252         execution.setVariable("subOperationType", "DELETE")
 
 253         execution.setVariable("initProgress", 20)
 
 254         execution.setVariable("endProgress",90)
 
 256         execution.setVariable("timeOut", TIMEOUT)
 
 258         LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
 
 262      * delete communication profile from AAI
 
 265     void delCSProfileFromAAI(DelegateExecution execution)
 
 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")
 
 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() : ""
 
 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")
 
 290             resourceClient.delete(resourceUri)
 
 291             LOGGER.debug("end delete communication service profile from AAI")
 
 295             String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
 
 296             LOGGER.error(any.printStackTrace())
 
 297             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
 
 303      * delete communication service from AAI
 
 306     void delCSFromAAI(DelegateExecution execution)
 
 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)
 
 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")
 
 323             LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
 
 324             exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
 
 328     void sendSyncError(DelegateExecution execution)
 
 330         LOGGER.debug("Starting sendSyncError")
 
 334             if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
 
 335                 WorkflowException wfe = execution.getVariable("WorkflowException")
 
 336                 errorMessage = wfe.getErrorMessage()
 
 338                 errorMessage = "Sending Sync Error."
 
 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>"""
 
 347             LOGGER.debug(buildworkflowException)
 
 348             sendWorkflowResponse(execution, 500, buildworkflowException)
 
 350         } catch (Exception ex) {
 
 351             LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
 
 356      * prepare update operation status
 
 359     void preFailedOperationStatus(DelegateExecution execution)
 
 361         LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
 
 363         execution.setVariable("progress", "100")
 
 364         execution.setVariable("result", "error")
 
 365         execution.setVariable("operationContent", "terminate service failure")
 
 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)
 
 373         LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
 
 377      * prepare Operation status
 
 379      * @param operationType
 
 381     private void setOperationStatus(DelegateExecution execution)
 
 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")
 
 395         requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
 
 398     void prepareFailureStatus(DelegateExecution execution)
 
 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")}")
 
 407      * check request json and save parameter to execution
 
 410      * @param isErrorException
 
 413     private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
 
 416         String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
 
 417         if (isBlank(paramValue)) {
 
 418             msg = "Input ${paraName} is null"
 
 422                 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
 
 426             execution.setVariable(paraName, paramValue)