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
22 import org.onap.aaiclient.client.aai.entities.uri.AAISimpleUri
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
54 class DeleteCommunicationService extends AbstractServiceTaskProcessor {
55 private final String PREFIX ="DeleteCommunicationService"
56 private final Long TIMEOUT = 60 * 60 * 1000
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)
64 void preProcessRequest(DelegateExecution execution) {
65 execution.setVariable("prefix",PREFIX)
68 LOGGER.trace("Starting preProcessRequest")
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")
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)
84 LOGGER.info("Input Request: ${siRequest}, reqId: ${requestId}, serviceInstanceId: ${serviceInstanceId}")
87 checkAndSetRequestParam(siRequest,"globalSubscriberId",false,execution)
88 checkAndSetRequestParam(siRequest,"serviceType",false,execution)
89 checkAndSetRequestParam(siRequest,"operationId",false,execution)
91 } catch (BpmnError e) {
94 msg = "Exception in preProcessRequest " + any.getCause()
96 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
98 LOGGER.trace("Exit preProcessRequest")
103 * prepare update operation status
106 void preInitUpdateOperationStatus(DelegateExecution execution){
107 LOGGER.trace(" ======== STARTED initUpdateOperationStatus Process ======== ")
109 execution.setVariable("result","processing")
110 execution.setVariable("progress","0")
111 execution.setVariable("operationContent","delete communication service operation start")
112 setOperationStatus(execution)
115 LOGGER.error("Exception Occured Processing initUpdateOperationStatus. Exception is:\n" + e)
116 execution.setVariable("CVFMI_ErrorResponse", "Error Occurred during initUpdateOperationStatus Method:\n" + e.getMessage())
118 LOGGER.trace("======== COMPLETED initUpdateOperationStatus Process ======== ")
125 void sendSyncResponse(DelegateExecution execution) {
126 LOGGER.debug("Begin sendSyncResponse")
129 String operationId = execution.getVariable("operationId")
130 String syncResponse = """{"operationId":"${operationId}"}""".trim()
131 sendWorkflowResponse(execution, 202, syncResponse)
133 } catch (Exception ex) {
134 String msg = "Exception in sendSyncResponse: " + ex.getMessage()
135 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
137 LOGGER.debug("Exit sendSyncResponse")
141 * query CommunicationSerive from AAI
142 * save e2eslice-service instance id and service name
145 void queryCommunicationSeriveFromAAI(DelegateExecution execution)
147 LOGGER.trace(" ***** begin queryCommunicationSeriveFromAAI *****")
148 String serviceInstanceId = execution.getVariable("serviceInstanceId")
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)
155 String serviceInstName = si.get()?.getServiceInstanceName()
156 String e2eSliceServiceInstId
159 List<Relationship> relationshipList = si.get().getRelationshipList()?.getRelationship()
160 for (Relationship relationship : relationshipList)
162 String relatedTo = relationship.getRelatedTo()
163 if (relatedTo == "service-instance")
165 String relatedLink = relationship.getRelatedLink()?:""
166 e2eSliceServiceInstId = relatedLink ? relatedLink.substring(relatedLink.lastIndexOf("/") + 1,relatedLink.length()) : ""
171 execution.setVariable("e2eSliceServiceInstanceId", e2eSliceServiceInstId)
172 execution.setVariable("serviceInstanceName", serviceInstName ?: "")
173 LOGGER.info("communication-service Id: ${serviceInstanceId}, e2eslice-service Id: ${e2eSliceServiceInstId}, serviceName: ${serviceInstName}")
175 LOGGER.debug(" ***** Exit queryCommunicationSeriveFromAAI *****")
181 * @param aaiObjectName
183 * @return AAIResultWrapper
185 private AAIResultWrapper queryAAI(DelegateExecution execution, AAIObjectName aaiObjectName, String instanceId, String errorMsg)
187 String globalSubscriberId = execution.getVariable("globalSubscriberId")
188 String serviceType = execution.getVariable("serviceType")
190 AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(instanceId))
191 if (!getAAIClient().exists(resourceUri)) {
192 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, errorMsg)
194 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
200 * 再次调用deleteE2EServiceInstance接口,然后获取到operationid,
202 void sendRequest2NSMFWF(DelegateExecution execution) {
203 LOGGER.debug("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 msoKey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
218 String basicAuth = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
219 def authHeader = utils.getBasicAuth(basicAuth, msoKey)
221 // String basicAuthValue = utils.encrypt(basicAuth, msoKey)
222 // String encodeString = utils.getBasicAuth(basicAuthValue, msoKey)
224 HttpClient httpClient = getHttpClientFactory().newJsonClient(new URL(url), ONAPComponents.SO)
225 // httpClient.addAdditionalHeader("Authorization", encodeString)
226 httpClient.addAdditionalHeader("Authorization", authHeader)
227 httpClient.addAdditionalHeader("Accept", "application/json")
228 Response httpResponse = httpClient.delete(requestBody)
229 handleNSSMFWFResponse(httpResponse, execution)
231 } catch (BpmnError e) {
234 String msg = "Exception in DeleteCommunicationService.preRequestSend2NSMF. " + any.getCause()
236 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
239 LOGGER.debug("exit preRequestSend2NSMF")
243 * prepare update operation status
246 private void handleNSSMFWFResponse(Response httpResponse, DelegateExecution execution){
247 LOGGER.debug(" ======== STARTED prepareUpdateOperationStatus Process ======== ")
249 int nsmfResponseCode = httpResponse.getStatus()
250 LOGGER.debug("nsmfResponseCode${nsmfResponseCode}")
252 if (nsmfResponseCode >= 200 && nsmfResponseCode < 204 && httpResponse.hasEntity()) {
253 String nsmfResponse = httpResponse.readEntity(String.class)
254 def e2eOperationId = jsonUtil.getJsonValue(nsmfResponse, "operationId")
255 execution.setVariable("e2eOperationId", e2eOperationId)
256 execution.setVariable("progress","20")
257 execution.setVariable("operationContent","waiting nsmf service delete finished")
259 execution.setVariable("currentCycle",0)
260 execution.setVariable("isNSMFTimeOut", "no")
261 execution.setVariable("isNSMFWFRspSucceed","yes")
265 String serviceName = execution.getVariable("serviceInstanceName")
266 execution.setVariable("progress", "100")
267 execution.setVariable("result", "error")
268 execution.setVariable("operationContent", "terminate service failure.")
269 execution.setVariable("reason","NSMF WF asynchronous response failed, status Code:${nsmfResponseCode}")
270 execution.setVariable("isNSMFWFRspSucceed","no")
271 LOGGER.error("nsmf async response error,nsmfResponseCode:${nsmfResponseCode},serivceName:${serviceName}")
273 setOperationStatus(execution)
274 LOGGER.debug("======== COMPLETED prepareUpdateOperationStatus Process ======== ")
278 * prepare to call sub process
281 void prepareCallCheckProcessStatus(DelegateExecution execution)
283 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Start")
285 def successConditions = new ArrayList<>()
286 successConditions.add("finished")
287 execution.setVariable("successConditions", successConditions)
289 def errorConditions = new ArrayList<>()
290 errorConditions.add("error")
291 execution.setVariable("errorConditions", errorConditions)
293 execution.setVariable("processServiceType", "communication service")
294 execution.setVariable("subOperationType", "DELETE")
295 execution.setVariable("initProgress", 20)
296 execution.setVariable("endProgress",90)
298 execution.setVariable("timeOut", TIMEOUT)
300 LOGGER.debug(PREFIX + "prepareCallCheckProcessStatus Exit")
304 * delete communication profile from AAI
307 void delCSProfileFromAAI(DelegateExecution execution)
309 LOGGER.debug("start delete communication service profile from AAI")
310 String globalSubscriberId = execution.getVariable("globalSubscriberId")
311 String serviceType = execution.getVariable("serviceType")
312 String serviceInstanceId = execution.getVariable("serviceInstanceId")
317 AAIPluralResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfiles())
318 AAIResultWrapper wrapper = getAAIClient().get(resourceUri, NotFoundException.class)
319 Optional<CommunicationServiceProfiles> csProfilesOpt = wrapper.asBean(CommunicationServiceProfiles.class)
320 if(csProfilesOpt.isPresent()){
321 CommunicationServiceProfiles csProfiles = csProfilesOpt.get()
322 CommunicationServiceProfile csProfile = csProfiles.getCommunicationServiceProfile().get(0)
323 profileId = csProfile ? csProfile.getProfileId() : ""
325 AAISimpleUri profileUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(serviceType).serviceInstance(serviceInstanceId).communicationServiceProfile(profileId))
326 if (!getAAIClient().exists(profileUri)) {
327 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "communication service profile was not found in aai")
330 getAAIClient().delete(profileUri)
331 LOGGER.debug("end delete communication service profile from AAI")
335 String msg = "delete communication service profile from aai failed! cause-"+any.getCause()
336 LOGGER.error(any.printStackTrace())
337 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
343 * delete communication service from AAI
346 void delCSFromAAI(DelegateExecution execution)
350 LOGGER.debug("start delete communication service from AAI")
351 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId")).serviceSubscription(execution.getVariable("serviceType")).serviceInstance(execution.getVariable("serviceInstanceId")))
352 getAAIClient().delete(serviceInstanceUri)
354 execution.setVariable("progress", "100")
355 execution.setVariable("result", "finished")
356 execution.setVariable("operationContent", "CSMF completes service terminated.")
357 setOperationStatus(execution)
358 LOGGER.debug("end delete communication service from AAI")
362 LOGGER.error("Error occured within delCSFromAAI method, cause: ${any.getCause()} ")
363 exceptionUtil.buildAndThrowWorkflowException(execution, 2500, "Error occured during delete communication service from aai")
367 void sendSyncError(DelegateExecution execution)
369 LOGGER.debug("Starting sendSyncError")
372 String errorMessage = "Sending Sync Error."
373 if (execution.getVariable("WorkflowException") instanceof WorkflowException) {
374 WorkflowException wfe = execution.getVariable("WorkflowException")
375 errorMessage = wfe.getErrorMessage()
378 String buildworkflowException =
379 """<aetgt:WorkflowException xmlns:aetgt="http://org.onap/so/workflow/schema/v1">
380 <aetgt:ErrorMessage>${MsoUtils.xmlEscape(errorMessage)}</aetgt:ErrorMessage>
381 <aetgt:ErrorCode>7000</aetgt:ErrorCode>
382 </aetgt:WorkflowException>"""
384 LOGGER.debug(buildworkflowException)
385 sendWorkflowResponse(execution, 500, buildworkflowException)
387 } catch (Exception ex) {
388 LOGGER.error("Sending Sync Error Activity Failed. " + "\n" + ex.getMessage())
393 * prepare update operation status
396 void preFailedOperationStatus(DelegateExecution execution)
398 LOGGER.debug(" ======== STARTED preFailedOperationStatus Process ======== ")
400 execution.setVariable("progress", "100")
401 execution.setVariable("result", "error")
402 execution.setVariable("operationContent", "terminate service failure")
404 WorkflowException wfex = execution.getVariable("WorkflowException") as WorkflowException
405 String errorMessage = wfex.getErrorMessage()
406 errorMessage = errorMessage.length() > 200 ? errorMessage.substring(0,200) + "......" : errorMessage
407 execution.setVariable("reason", errorMessage)
408 setOperationStatus(execution)
410 LOGGER.debug("======== COMPLETED prepareEndOperationStatus Process ======== ")
414 * prepare Operation status
416 * @param operationType
418 private void setOperationStatus(DelegateExecution execution)
420 OperationStatus operationStatus = new OperationStatus()
421 operationStatus.setServiceId(execution.getVariable("serviceInstanceId"))
422 operationStatus.setOperationId(execution.getVariable("operationId"))
423 operationStatus.setUserId(execution.getVariable("globalSubscriberId"))
424 //interface not support update
425 operationStatus.setServiceName(execution.getVariable("serviceInstanceName"))
426 operationStatus.setResult(execution.getVariable("result"))
427 operationStatus.setProgress(execution.getVariable("progress"))
428 operationStatus.setOperationContent(execution.getVariable("operationContent"))
429 operationStatus.setReason(execution.getVariable("reason")?:"")
430 operationStatus.setOperation("DELETE")
432 requestDBUtil.prepareUpdateOperationStatus(execution, operationStatus)
435 void prepareFailureStatus(DelegateExecution execution)
437 execution.setVariable("result", "finished")
438 execution.setVariable("progress", "100")
439 execution.setVariable("operationContent", "terminate service failure.")
440 setOperationStatus(execution)
441 LOGGER.debug("${PREFIX}-prepareFailureStatus,result:${execution.getVariable("result")}, reason: ${execution.getVariable("reason")}")
445 * check request json and save parameter to execution
448 * @param isErrorException
451 private void checkAndSetRequestParam(String siRequest, String paraName, boolean isErrorException, DelegateExecution execution)
454 String paramValue = jsonUtil.getJsonValue(siRequest, paraName)
455 if (isBlank(paramValue)) {
456 msg = "Input ${paraName} is null"
460 exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
464 execution.setVariable(paraName, paramValue)